Python数据预处理之异常值的处理——【自定义的three_sigma()函数、boxplot()方法】


基于3σ原则检测异常值

3σ原则,又称拉依达准则。是指假设一组检测数据只含有随机误差。对其进行计算处理得到标准偏差,按一定概率确定一个区间,凡是超过这个区间的误差都是粗大误差,在此误差范围内的数据应予以剔除。

正态分布概率公式中,σ表示标准差,μ表示平均数,f(x)表示正态分布函数。

正态分布公式
在这里插入图片描述

正态曲线下,

横轴区间(μ-σ,μ+σ)内的面积为68.268949%。

P{|X-μ|<σ}=2Φ(1)-1=0.6826

横轴区间(μ-2σ,μ+2σ)内的面积为95.449974%。

P{|X-μ|<2σ}=2Φ(2)-1=0.9544

横轴区间(μ-3σ,μ+3σ)内的面积99.730020%。

P{|X-μ|<3σ}=2Φ(3)-1=0.9974

由于“小概率事件”和假设检验的基本思想 “小概率事件”通常指发生的概率小于5%的事件,认为在一次试验中该事件是几乎不可能发生的。

由上可知,X落在(μ-3σ,μ+3σ)以外的概率小于千分之三,在实际问题中常认为相应的事件是不会发生的,基本上可以把区间(μ-3σ,μ+3σ)看作是随机变量X实际可能的取值区间,超过这个区间的就属于异常值,应予以剔除。


代码实现

import numpy as np
import pandas as pd


def three_sigma(ser1):  # ser1表示传入DataFrame的某一列
    mean_value = ser1.mean()  # 求平均值
    std_value = ser1.std()  # 求标准差
    rule = (mean_value - 3 * std_value > ser1) | (ser1.mean() + 3 * ser1.std() < ser1)
    # 位于(u-3std,u+3std)区间的数据是正常的,不在这个区间的数据为异常的
    # 一旦发现有异常值,就标注为True,否则标注为False
    index = np.arange(ser1.shape[0])[rule]  # 返回异常值的位置索引
    outrange = ser1.iloc[index]  # 获取异常数据
    return outrange

测试

将符合正态分布的包含异常值的测试数据保存在D:\数据分析\data.xlsx中。使用Pandas的read_excel()函数从文件中读取数据,并转换为DataFrame对象。之后分别对data中的A列数据和B列数据进行检测。

data = pd.read_excel(r'D:\数据分析\data.xlsx')
print(data)
print(three_sigma(data['A']))
print(three_sigma(data['B']))

输出结果:

    Unnamed: 0    A  B
0            0    1  2
1            1    2  3
2            2    3  8
3            3    4  5
4            4    5  6
5            5  560  7
6            6    2  8
7            7    3  9
8            8    4  0
9            9    5  3
10          10    3  4
11          11    2  5
12          12    4  6
13          13    5  7
14          14    5  2
15          15   23  4
16          16    2  5

5    560
Name: A, dtype: int64

Series([], Name: B, dtype: int64)

基于箱型图检测异常值

箱型图是一种用作显示一组数据分散情况的统计图。在箱型图中,异常值通常被定义为小于QL-1.5QR或大于QU+1.5IQR的值。其中:

QL:下四分位数,表示全部观察值中有四分之一的数据取值比它大。

QU:上四分位数,表示全部观察值中有四分之一的数据取值比它小。

IQR:四分位数间距,是QU与QL之差,其间包含了全部观察值的一半。


箱型图是根据实际数据进行绘制,对数据没有任何要求(3σ原则要求数据服从正态分布或近似正态分布)。箱型图判断异常值的标准是以四分位数和四分位距为基础的。

Pandas中提供了一个专门用来绘制箱型图的boxplot()方法。

df = pd.DataFrame({'A': [1, 2, 3, 4],
                   'B': [2, 3, 4, 5],
                   'C': [1, 4, 7, 4],
                   'D': [1, 5, 30, 3]})
print(df.boxplot(column=['A', 'B', 'C', 'D']))

输出结果:
在这里插入图片描述


异常值的处理

检测出异常值后,通常会才用如下四种方式处理这些异常值:

1、直接将含有异常值的记录删除

2、用具体的值来进行替换,可用前后两个观测值的平均值修正该异常值

3、不处理,直接在具有异常值的数据集上进行统计分析

4、视为缺失值,利用缺失值的处理方法修正该异常值

异常数据被检测出来之后,需要进一步确认他们是否为真正的异常值,等确认完以后再决定选用哪种方法进行解决。

如果希望对异常值进行修改(执行操作2),则可以使用Pandas中replace()方法进行替换,该方法不仅可以对单个数据进行替换,也可以多个数据执行批量替换操作。

replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method=‘pad’)

部分参数:

to_replace:表示查找被替换值的方式

value:用来替换任何匹配to_replace的值,默认值为None

limit:表示前向或后向填充的最大尺寸间隙

regex:接收布尔值或与to_replace相同的类型,默认为False,表示是否将to_replace和value解释为正则表达式

method:替换时使用的方法,pad/ffill表示前向填充,bfill表示后向填充


replace()方法的使用

print(df.replace(to_replace=30, value=3))
print(data.replace(to_replace=data.loc[5, ['A']], value=6))

输出结果:

AxesSubplot(0.125,0.11;0.775x0.77)
   A  B  C  D
0  1  2  1  1
1  2  3  4  5
2  3  4  7  3
3  4  5  4  3
    Unnamed: 0   A  B
0            0   1  2
1            1   2  3
2            2   3  8
3            3   4  5
4            4   5  6
5            5   6  7
6            6   2  8
7            7   3  9
8            8   4  0
9            9   5  3
10          10   3  4
11          11   2  5
12          12   4  6
13          13   5  7
14          14   5  2
15          15  23  4
16          16   2  5
  • 9
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是一个简单的 Python 数据预处理实例: 假设我们有一个名为“customers.csv”的客户数据集,其中包含客户姓名、年龄、性别、购买历史和信用分数等信息。我们想要对该数据集进行一些预处理,以便用于进一步的分析和建模。 1. 导入必要的库 ```python import pandas as pd import numpy as np ``` 2. 读取数据集 ```python data = pd.read_csv('customers.csv') ``` 3. 检查数据质量 ```python # 查看前5行数据 data.head() # 查看数据维度 data.shape # 检查缺失值 data.isnull().sum() # 检查重复值 data.duplicated().sum() # 查看数据类型 data.dtypes ``` 4. 处理缺失值 ```python # 删除缺失值 data.dropna(inplace=True) # 填充缺失值 data.fillna(value=0, inplace=True) ``` 5. 处理重复值 ```python # 删除重复值 data.drop_duplicates(inplace=True) ``` 6. 处理离群值 ```python # 使用箱线图检测离群值 import seaborn as sns sns.boxplot(x=data['age']) # 删除离群值 Q1 = data['age'].quantile(0.25) Q3 = data['age'].quantile(0.75) IQR = Q3 - Q1 data = data[(data['age'] >= Q1 - 1.5*IQR) & (data['age'] <= Q3 + 1.5*IQR)] ``` 7. 处理数据类型 ```python # 转换数据类型 data['age'] = data['age'].astype('int') data['credit_score'] = data['credit_score'].astype('float') # 对分类变量进行编码 from sklearn.preprocessing import LabelEncoder le = LabelEncoder() data['gender'] = le.fit_transform(data['gender']) ``` 8. 特征缩放 ```python # 使用 MinMaxScaler 进行特征缩放 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() data[['age', 'credit_score']] = scaler.fit_transform(data[['age', 'credit_score']]) ``` 以上是一个简单的 Python 数据预处理实例,其中包括数据质量检查、缺失值处理、重复值处理、离群值处理、数据类型处理和特征缩放等常见的预处理步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

·Jormungand

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值