Pandas按组分离并剔除异常值。

6
我想按组的方式基于99%分位数来移除离群值。
 import pandas as pd
 df = pd.DataFrame({'Group': ['A','A','A','B','B','B','B'], 'count': [1.1,11.2,1.1,3.3,3.40,3.3,100.0]})

在输出结果中,我希望从A组中删除11.2,在B组中删除100。因此,在最终数据集中只会有5个观测值。

wantdf = pd.DataFrame({'Group': ['A','A','B','B','B'], 'count': [1.1,1.1,3.3,3.40,3.3]})

我已经尝试了这个方法,但是没有得到期望的结果。

df[df.groupby("Group")['count'].transform(lambda x : (x<x.quantile(0.99))&(x>(x.quantile(0.01)))).eq(1)]

2
df.groupby('Group')['count'].transform(lambda x : x<=x.quantile(0.001)) - BENY
2个回答

16

这是我的解决方案:

def is_outlier(s):
    lower_limit = s.mean() - (s.std() * 3)
    upper_limit = s.mean() + (s.std() * 3)
    return ~s.between(lower_limit, upper_limit)

df = df[~df.groupby('Group')['count'].apply(is_outlier)]

您可以编写自己的is_outlier函数


4
这个答案比标记的答案更加简明易读。 - mc51
如果你想使用百分位数而不是3个标准差,可以使用s.quantile(.01)表示下限,s.quantile(.99)表示上限。 - ryoung29
顺便提一下,这不会从A组中删除11.2,也不会从B组中删除100,无论是+/-3SD还是+/-2SD。只有在1SD的情况下才会被删除。这是因为值非常少吗?仅凭外观,11.2和100似乎是异常值。 - Gupta
我认为这可能是由于样本量非常小且正态性假设不正确所导致的。参考:https://stats.stackexchange.com/questions/78609/outlier-detection-in-very-small-sets - Gupta

4

我认为您不希望使用分位数,因为这将排除您的较低值:

import pandas as pd
df = pd.DataFrame({'Group': ['A','A','A','B','B','B','B'], 'count': [1.1,11.2,1.1,3.3,3.40,3.3,100.0]})
print(pd.DataFrame(df.groupby('Group').quantile(.01)['count']))

输出:

       count
Group       
A        1.1
B        3.3

这些不是离群值,对吧?所以你不希望把它们排除在外。

也许你可以尝试通过使用中位数的标准差来设置左右限制?虽然有点啰嗦,但它能给你正确的答案:

left = pd.DataFrame(df.groupby('Group').median() - pd.DataFrame(df.groupby('Group').std()))
right = pd.DataFrame(df.groupby('Group').median() + pd.DataFrame(df.groupby('Group').std()))

left.columns = ['left']
right.columns = ['right']

df = df.merge(left, left_on='Group', right_index=True)
df = df.merge(right, left_on='Group', right_index=True)

df = df[(df['count'] > df['left']) & (df['count'] < df['right'])]
df = df.drop(['left', 'right'], axis=1)
print(df)

输出:

  Group  count
0     A    1.1
2     A    1.1
3     B    3.3
4     B    3.4
5     B    3.3

2
有没有更简单的方法?看起来步骤太多了。我们能否将其合并为小代码? - Kumar AK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接