我有一个带有价格列(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())
但是异常值过滤器无法正常工作。
答案 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