pandas数据的异常值判断、可视化、处理方式
回想一下我们小时候参加唱歌比赛,最后算分的时候总会去掉一个最高分,去掉一个最低分,将剩下的分数进行去平均。这里面就有筛选异常值的思想。一个非常夸张的异常值可能会造成对最后统计结果产生比较大的影响。所以,在这里,我们介绍两种办法来判断异常值,并使用箱线图进行显示。
异常值的判断
1、使用均值和标准差进行判断
mean 为数据的均值
std 为数据的标准差
数据的正常范围为 【mean-2 × std,mean+2 × std】
接下来我们使用代码来看看
import pandas as pd
import numpy as np
tips = pd.read_csv('tips.csv')
tipmean=tips['tip'].mean()
tipstd = tips['tip'].std()
topnum1 =tipmean+2*tipstd
bottomnum1 = tipmean-2*tipstd
print(tips.head(10))
print("正常值的范围:",topnum1,bottomnum1)
print("是否存在超出正常范围的值:",any(tips['tip']>topnum1))
print("是否存在小于正常范围的值:",any(tips['tip']<bottomnum1))
咱们先看输出结果吧:
- 首先咱们读入了tips.csv文件,将前十条数据输出到控制台中
- 我们这次主要使用的是文件中的tip这一列数据,通过mean()、std()两种方法分别计算出了这一列数据的均值和标准差。
- 通过any()函数分别判断数据中是否存在异常值
- 结果显示,存在超出正常范围的异常值,不存在小于正常范围的异常值。
使用上四中位数和下四中位数进行异常值判定
mean1 为上四中位数(就是将数据按从小到大排列,取3/4这个位置的数)
mean2 为下四中位数(同上,取1/4位置的数)
mean3 为中位差 mean3 = mean1-mean2
正常值的范围应在【mean2-1.5×mean3,mean1+1.5×mean2】
下面看代码:
import pandas as pd
import numpy as np
tips = pd.read_csv('tips.csv')
mean1 = tips['tip'].quantile(q=0.25)#下四分位差
mean2 = tips['tip'].quantile(q=0.75)#上四分位差
mean3 = mean2-mean1#中位差
topnum2 = mean2+1.5*mean3
bottomnum2 = mean2-1.5*mean3
print("正常值的范围:",topnum2,bottomnum2)
print("是否存在超出正常范围的值:",any(tips['tip']>topnum2))
print("是否存在小于正常范围的值:",any(tips['tip']<bottomnum2))
先来看结果:
- quantile(q=0.25)和quantile(q=0.75) 分别是取下四中位数和上四中位数的值。其余与上面类似。
对比这两种方法,从结果上来看,差距不大,相对而言,matplotlib包中的箱线图使用的是第二种方式进行异常值分析。咱们平常使用的话,可以做一下比较,选取最适合自己数据的一种方法。
通过可视化进行异常值分析判断
接着上面的继续,上面我们提供了两种方法进行异常值的判断,接下来我们使用python中matplotlib的箱线图进行展示。箱线图是采用了上下四中位数的方法,也就是第二种方法。
先上代码:
import matplotlib.pyplot as plt
plt.boxplot(x=tips['tip'])
plt.show()
先看结果:
- 首先导入matplotlib的pyplot包
- 使用plt.boxplot(x=tips[‘tip’]) 这个就是matplotlib的箱线图的方法,这里不介绍它的其他参数,具体用法我会在matplotlib那里做详细介绍的。传入数据tips[‘tip’]
- plt.show()将图形显示出来
- 从结果图中,我们可以看到,上下两条直线就是正常值的上下限,下面那条线下面没有任何东西,代表没有小于下限的异常值,上面那条线上有许多⭕,代表着有许多超出上限的异常值。这些与我们之前的判断一致。
- 这时候大家可能会有个疑问,为什么咱们上面算的下限是负数,为什么图片中下限不是负数呢。为了解答这个问题,我特意向数据添加了一条数据,tip值为0.1。咱们看看添加后这条数据的图像:
这里我判断,我下限这里是取数据中最小的,并不是咱们之前计算的负数,暂且这么理解吧。
异常值处理
通常的处理方式是取数据中的最大最小值进行异常值替换。
replace_value1=tips['tip'][tips['tip']<topnum2].max()
tips.loc[tips['tip']>topnum2,'tip']=replace_value
replace_value2=tips['tip'][tips['tip']>bottomnum2].min()
tips.loc[tips['tip']<bottomnum2,'tip']=replace_value2
- tips[‘tip’][tips[‘tip’]<topnum2]首先取出小于正常值上限的数据,然后从这些数据中使用max()方法,找出最大值。
- 取最小值同理。