首页 > 解决方案 > 分组排除异常值的最有效方法是什么

问题描述

假设我有这样的数据框

channel | ID | cnt_txn | amount
   A    |  1 |    3    |  15
   A    |  2 |    5    |  20
   B    |  1 |    4    |  12
   C    |  3 |    3    |  12
   C    |  2 |    10   |  10

我有这个功能

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)

按通道分组并将is_outlier(或类似逻辑)功能应用于按通道分组中的每个数据的最简单和易读的方法是什么

我努力了

df.groupby(['vertical'])['cnt_txn','amount'].apply(is_outlier)

它导致

AttributeError: 'DataFrame' 对象没有属性 'between'

我猜它没有循环数据框中的每一列

如果有人可以解释这一点并提供解决方案将不胜感激,在此先感谢

标签: pythonpython-3.xpandaspandas-groupby

解决方案


根据目前的知识,感谢@Phung Duy Phong指出逻辑。

离群函数应该看起来像这样,以加快 groupby 的性能

def is_outlier(x):
    return (x<x.quantile(0.95))&(x>(x.quantile(0.05)))

和 groupby 语句应该是这样的

df[df.groupby(['channel'])['cnt_txn','amount'].apply(is_outlier).eq(1).all(axis=1)]

注意到.eq(1)进来是为了简化结果TrueFalse不是Nan有价值

并且.all(axis=1)是将返回数组组合成一维,说明所有列必须truetrue

最后df[arrayOfTrueFalse]将返回没有异常值的数据帧


推荐阅读