使用分组依据之前过滤异常值

时间:2018-11-21 15:17:25

标签: python pandas numpy

我有一个带有价格列(p)的数据框,并且我有一些不需要的值,例如(0,1.50,92.80,0.80)。在按产品代码计算价格平均值之前,我想删除这些离群值

                Code    Year    Month  Day   Q      P
0               100     2017       1    4   2.0  42.90
1               100     2017       1    9   2.0  42.90
2               100     2017       1   18   1.0  45.05
3               100     2017       1   19   2.0  45.05
4               100     2017       1   20   1.0  45.05
5               100     2017       1   24  10.0  46.40
6               100     2017       1   26   1.0  46.40
7               100     2017       1   28   2.0  92.80
8               100     2017       2    1   0.0   0.00
9               100     2017       2    7   2.0   1.50
10              100     2017       2    8   5.0   0.80
11              100     2017       2    9   1.0  45.05
12              100     2017       2   11   1.0   1.50
13              100     2017       3    8   1.0  49.90
14              100     2017       3   17   6.0  45.05
15              100     2017       3   24   1.0  45.05
16              100     2017       3   30   2.0   1.50

如何最好地过滤每个产品的异常值(按代码分组)?

我尝试过:

stds = 1.0  # Number of standard deviation that defines 'outlier'.
z = df[['Code','P']].groupby('Code').transform(
    lambda group: (group - group.mean()).div(group.std()))
outliers = z.abs() > stds
df[outliers.any(axis=1)]

然后:

print(df[['Code', 'Year', 'Month','P']].groupby(['Code', 'Year', 'Month']).mean())

但是异常值过滤器无法正常工作。

2 个答案:

答案 0 :(得分:2)

IIUC您可以在EID LOGDATE LOG 00004 19-NOV-18 Database user USER1; Department ID from '99999' to ''; 00004 19-NOV-18 Database user USER1; Department ID from '' to '22222'; 上使用groupby,在Code上进行z得分计算,并过滤P得分是否大于阈值:

z

答案 1 :(得分:1)

您有正确的想法。只需通过outliers['P']~系列相反的布尔值,然后通过loc过滤数据框即可:

res = df.loc[~outliers['P']]\
        .groupby(['Code', 'Year', 'Month'], as_index=False)['P'].mean()

print(res)

   Code  Year  Month          P
0   100  2017      1  44.821429
1   100  2017      2  45.050000
2   100  2017      3  46.666667