【问题标题】:pandas group by remove outlierspandas group by 删除异常值
【发布时间】:2018-10-28 01:33:03
【问题描述】:

我想按组删除基于百分位 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)]

【问题讨论】:

  • df.groupby('Group')['count'].transform(lambda x : x&lt;=x.quantile(0.001))

标签: python python-3.x pandas pandas-groupby


【解决方案1】:

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

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】:

这是我的解决方案:

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 函数

【讨论】:

  • 这比标记的答案更简洁易读。
  • 如果您想要百分位数而不是 3 SD,请使用 s.quantile(.01) 作为下限,使用 s.quantile(.99) 作为上限
  • 顺便说一句,这不会删除 A 组中的 11.2 和 B 组中的 100 和 +/3 SD 或 +/- 2SD。只有 1 个 SD,它们才会被删除。是因为价值非常低吗? 11.2 和 100 看起来似乎是异常值
  • 我认为这可能是由于样本量非常小并且正态性假设不正确。参考:stats.stackexchange.com/questions/78609/…
猜你喜欢
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2017-11-15
  • 1970-01-01
  • 2018-03-05
  • 2023-01-15
相关资源
最近更新 更多