赞
踩
开挖!
关于箱线图,核心理念就是找出上四分位数和下四分位数,定义二者的差为
I
Q
R
IQR
IQR。上下四分位数分别向上下扩展
1.5
I
Q
R
1.5IQR
1.5IQR定义为上界和下界,在此之外的数据被认为是异常数据。
这当然是合理的,关键在于四分位数如何求。
这是实训中给出的方法,这当然是错误的。
四分位数是没有办法仅通过一条公式算出来的,肯定要分类讨论。由于是除以四所以分为
0.25
,
0.5
,
0.75
,
0
0.25,0.5,0.75,0
0.25,0.5,0.75,0四种情况。
靠哪边近哪边占据更大权重才是合理的,比如
0.25
0.25
0.25的情况下就有
Q
i
=
0.75
⋅
x
[
i
(
l
+
1
)
/
/
4
]
+
0.25
⋅
x
[
i
(
l
+
1
)
/
/
4
+
1
]
Q_i=0.75\cdot x[i(l+1)//4]+0.25\cdot x[i(l+1)//4+1]
Qi=0.75⋅x[i(l+1)//4]+0.25⋅x[i(l+1)//4+1]。
其余三种情况同理。
但是分类讨论比较麻烦,我们可以借助quantile函数帮助我们直接求出上下四分位点。
求出分位点之后,我们理所当然知道了上限和下限。
此时我们可以借助
S
e
r
i
e
s
Series
Series数据类型的特殊运算性质我们求出异常值
b
o
o
l
bool
bool类型的
s
e
r
i
e
s
series
series,然后将他取反后在原
s
e
r
i
e
s
series
series中去除即可。
import pandas as pd import matplotlib.pyplot as plt from scipy import stats import numpy as np data = pd.read_csv("src/death.csv", index_col='Unnamed: 0') data = data.dropna(axis=1, thresh=data.shape[0] * 0.2) data = data.dropna(axis=0, thresh=data.shape[1] * 0.2) a = pd.isna(data).sum() cols = [x for i, x in enumerate(a.index) if a[i] > 0] mode_list = 'FIPS Admin2' for i in cols: if mode_list.find(i) != -1: data[i] = data[i].fillna(data[i].mode().iloc[0]) else: data[i] = data[i].fillna(data.mean()[i]) cols = '2008/10/20,2008/11/20,2008/12/20'.split(',') x = data[cols] ########## Begin ########## Q1 = x.quantile(0.25) Q3 = x.quantile(0.75) IQR = Q3 - Q1 lower_limit = Q1 - 1.5 * IQR upper_limit = Q3 + 1.5 * IQR outliers_index = (x < lower_limit) | (x > upper_limit) x_c1 = x[~outliers_index] print(outliers_index.sum()) ########## End ########## x_c1.boxplot() plt.savefig(r'src/step1/ans_img') plt.show()
解决问题的关键在于两点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。