问题描述
我在 df
中有一个数字列的示例,它有 10 个其他列(数字和分类):
Units
-12
4
4
5
1
5
12
6
34
6
7
12
745
我想应用公式:
Low outlier: q1-(1.5*iqr)
High outlier: q3+(1.5*iqr)
我知道 iqr
中有 scipy
:from scipy.stats import iqr
并且使用 numpy
我可以计算 q1
(第一四分位数)和 q3
(第三个四分位数)如下:
from scipy.stats import iqr
import numpy as np
q1=np.percentile(df.Units,25)
q3=np.percentile(df.Units,75)
mask = df['Units'].between(q1,q3,inclusive=True)
iqr = df.loc[mask,'Units']
但是在计算上述公式时缺少两个步骤:
- 处理
NaN
值:我不想将它们从我的列中删除,而只是从计算中排除它们; - 正确应用公式
低离群值:q1-(1.5*iqr)
高离群值:q3+(1.5*iqr)
我想说,也许可以通过使用 between
或仅过滤低于/高于根据上述公式计算的值的值。
解决方法
使用 df.query
进行惰性尝试,从计算中排除 NaN
并将它们保留在最终查询中:
from scipy.stats import iqr
df = pd.DataFrame([-12,4,5,1,12,6,34,7,np.nan,745],columns=["Units"])
q1 = np.nanpercentile(df.Units,25)
q3 = np.nanpercentile(df.Units,75)
IQR = iqr(df.Units,nan_policy="omit")
df.query("Units.isnull() or ((@q1 - 1.5*@IQR) <= Units <= (@q3 + 1.5*@IQR))")
给出(希望)预期的结果:
Units
1 4.0
2 4.0
3 5.0
4 1.0
5 5.0
6 12.0
7 6.0
9 6.0
10 7.0
11 NaN
12 12.0