我有一个很少列的熊猫数据帧。

现在我知道某些行是基于某个列值的异常值。

例如

列“Vol”的所有值都在12xx左右,其中一个值是4000(离群值)。

现在我想排除那些Vol列像这样的行。

所以,本质上,我需要在数据帧上放一个过滤器,这样我们就可以选择所有的行,其中某一列的值距离平均值在3个标准差之内。

实现这一点的优雅方式是什么?


当前回答

去掉离群值的函数

def drop_outliers(df, field_name):
    distance = 1.5 * (np.percentile(df[field_name], 75) - np.percentile(df[field_name], 25))
    df.drop(df[df[field_name] > distance + np.percentile(df[field_name], 75)].index, inplace=True)
    df.drop(df[df[field_name] < np.percentile(df[field_name], 25) - distance].index, inplace=True)

其他回答

另一种选择是转换数据,以减轻异常值的影响。你可以通过winsorize你的数据来做到这一点。

import pandas as pd
from scipy.stats import mstats
%matplotlib inline

test_data = pd.Series(range(30))
test_data.plot()

# Truncate values to the 5th and 95th percentiles
transformed_test_data = pd.Series(mstats.winsorize(test_data, limits=[0.05, 0.05])) 
transformed_test_data.plot()

对于数据框架中的每个系列,您可以使用between和分位数来删除异常值。

x = pd.Series(np.random.normal(size=200)) # with outliers
x = x[x.between(x.quantile(.25), x.quantile(.75))] # without outliers

如果你的数据帧有异常值,有很多方法可以处理这些异常值:

大多数都在我的文章中提到过:读一读

在这里找到代码:Notebook

删除至少一列中有异常值的所有行

如果你的数据框架中有多列,并且想要删除至少一列中有异常值的所有行,下面的表达式可以一次性完成:

import pandas as pd
import numpy as np
from scipy import stats


df = pd.DataFrame(np.random.randn(100, 3))

df[(np.abs(stats.zscore(df)) < 3).any(axis=1)]

描述:

中的每个列,它首先计算每个值的z分数 列,相对于列的均值和标准差。 然后取绝对z分数,因为方向没有 物质,只有当它低于阈值时。 All(轴=1)确保对于每一行,所有列都满足 约束。 最后,这个条件的结果被用于索引数据帧。

基于单个列筛选其他列

为zscore指定一列,例如df[0],并删除.all(axis=1)。

df[(np.abs(stats.zscore(df[0])) < 3)]

如果你喜欢方法链接,你可以得到所有数值列的布尔条件,如下所示:

df.sub(df.mean()).div(df.std()).abs().lt(3)

每一列的每个值都将根据其是否距离平均值小于三个标准差而转换为True/False。