使用pandas识别统计异常值:按组和单独列进行分组

4

我正在尝试理解如何识别统计学上的离群值,并将其发送到电子表格。我需要按索引分组行,然后查找特定列的标准差,任何超过标准差的值都将用于填充电子表格。

df = pandas.DataFrame({'Sex': ['M','M','M','F','F','F','F'], 'Age': [33,42,19,64,12,30,32], 'Height': ['163','167','184','164','162','158','160'],})

使用这样的数据集,我想按性别分组,然后找到超过年龄或身高标准差的条目。大多数示例都是针对整个数据集的标准差,而不是按列分解的。还会有其他列,比如州,所以我不需要每列的标准差,只需要从集合中选择特定的列。
希望输出仅包含在任一列中被识别为统计异常值的行的数据。例如:
0  M  64  164
1  M  19  184

假设64岁的男性身高超过了男性身高标准差,而184厘米的身高超过了男性身高标准差。


好的,这里有一个问题要问你。你是指相对于MEAN还是相对于STD?因为在我看来,STD不是正确的过滤对象。 - cs95
如果您也提供了一些期望的输出,那将会很有帮助。 - cs95
cmaher - 嗯,由于我对pandas完全不熟悉,而且对python也比较新手,所以我最初是追求将它们分组,然后找到每个组的每列的标准差,我打算使用for语句来迭代每一行,以检查标准差是否大于平均值,但是从更多的pandas问题中探索,看起来这种情况可以在没有过多编码的情况下处理。coldspeed - 我不确定我完全理解你的问题,但我想要任何超过3个标准差的值的行。标准差是按组计算的,因此m和f的标准差是不同的。 - Thomas
身高的标准差为11。一切都超过了11。我猜这不是你的意思。 - cs95
正确的,我想要超过平均值3个标准差的任何内容。抱歉,我以为使用标准差就已经包含了这个意思。样本输出格式: 正確的,我想要超過平均值3個標準差的任何內容。抱歉,我以為使用標準差就已經包含了這個意思。 - Thomas
1个回答

6
首先,将您的身高从字符串转换为值。
df['Height'] = df['Height'].astype(float)

然后,您需要使用transformSex分组,创建一个布尔指示器,标记是否在该组中任何一个AgeHeight是统计异常值。

stds = 1.0  # Number of standard deviation that defines 'outlier'.
z = df[['Sex', 'Age', 'Height']].groupby('Sex').transform(
    lambda group: (group - group.mean()).div(group.std()))
outliers = z.abs() > stds
>>> outliers
     Age Height
0  False  False
1  False  False
2   True   True
3   True   True
4   True  False
5  False   True
6  False  False

现在过滤包含任何异常值的行:
>>> df[outliers.any(axis=1)]
   Age  Height Sex
2   19     184   M
3   64     164   F
4   12     162   F
5   30     158   F

如果您只关心分布的上行(即值 > 平均值 + 2个标准偏差),那么请省略 .abs(),即 lambda group: (group - group.mean()).div(group.std()) > stds


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