使用百分位数从熊猫数据框中删除异常值

Posted

技术标签:

【中文标题】使用百分位数从熊猫数据框中删除异常值【英文标题】:Removing outliers from pandas data frame using percentile 【发布时间】:2018-09-05 22:52:55 【问题描述】:

我正在点击此链接来删除异常值,但这里有些逻辑错误..

Remove Outliers in Pandas DataFrame using Percentiles

我有一个数据集,第一列为“id”,最后一列为“label”。

这是我的一段代码,我要删除标签和 id 列,然后附加它:

def processing_data(train_data,test_data):
    #computing percentiles.
    low = .05
    high = .95
    filt_df = train_data.loc[:, train_data.columns != 'id']
    filt_df= filt_df.loc[:, filt_df.columns != 'label']
    quant_df = filt_df.quantile([low, high])
    print(quant_df)

    #filtering values based on computed percentiles. To do that use an apply by columns.
    print("Before removing outlier",filt_df,filt_df.shape)
    train_data1 = filt_df.apply(lambda x: x[(x>=quant_df.loc[low,x.name]) & (x <=quant_df.loc[high,x.name])], axis=0)
    print("After removing outlier,",train_data1,train_data1.shape)
    print(train_data1.isnull().sum())
    train_data1= pd.concat([train_data.loc[:,'id'], train_data1], axis=1)
    train_data=pd.concat([train_data.loc[:,'label'], train_data1], axis=1)
    #train_data.dropna(inplace=True)

    #train_data.fillna(0)
    #test_data.fillna(0)
    #print(train_data)
    #print(np.isnan(train_data).any().sum())
    return train_data,test_data

输出:所有行都包含一些 NaN 值,当我这样做时 train_data.dropna(inplace=True) 所有行都被删除。 奇怪!!

我该如何解决这个问题?当我在异常值处理后 concat id 和 label 列时,我觉得那里有些可疑?

这是数据集:

id  feature0    feature1    feature2    feature3    feature4    feature249  label
0   25.20824887 -16.7457484 50.86994402 5.593471686 1.188262678   1
1   -86.93144987    0.428227194 2.87483597  -8.064850183    6.056867093     2 
2   42.16093367 7.85701304  151.6127571 9.639675583 5.570138511             0
3   20.66694385 8.680641918 -56.44917913    -9.814779803    -2.382979151    1
4   35.9466789  4.57373573  -28.16021186    -6.91297056 4.879375409         0

【问题讨论】:

您是在尝试dropna() 还是fillna()(两者都有)? dropna() 具有默认参数 'any'axis = 0,这意味着如果任何行包含 NaN,它将被删除。您可以尝试将 'any' 更改为 'all' 但我怀疑这就是您要找的。​​span> 那只是为了探索输出。我只想从数据集中删除异常值。 您能否发布一些示例起始数据以及您希望它的外观? 一个minimal reproducible example,包括一些与你的函数一起运行的数据,在这里会有帮助。 @DreamerP 您不需要上传完整的数据集。如果您有 excel,只需复制前 15-20 行数据并将其粘贴到此处并将其格式化为代码。应该够了。 【参考方案1】:

当我用你的例子运行你的代码时,我得到了一个 ValueError。我发现这个问题提到浮点数据帧元素分位数有不稳定的行为,它返回 NaN 或 ValueError https://github.com/pandas-dev/pandas/issues/14564 。我认为在这种情况下,它是 int 的 249 列,而其余的是浮点数。当我filt_df = pd.DataFrame(filt_df, dtype=float) 强制所有列浮动时,它运行良好。

每行中的 NaN 是当您按低和高过滤时放置的。示例中的每一行确实至少有一个超出 .05/.95 边界的值(您的数据可能比您想象的要平坦得多)。这意味着当您 dropna 并且它默认为“任何”时,所有行都将被删除。您可以通过将“任何”更改为“全部”或其他选项来更改 dropna 的操作方式。可能更好地调整您的上限/下限以更符合您的数据分布。请记住,即使您的边界对于每个添加的列都是非常独特的,但每行中至少有一个值超出这些边界的可能性越来越大。

【讨论】:

以上是关于使用百分位数从熊猫数据框中删除异常值的主要内容,如果未能解决你的问题,请参考以下文章

在大熊猫DataFrame中按组删除异常值的更快方法[重复]

如何一次性检测和删除熊猫数据帧每一列的异常值? [复制]

熊猫数据框 - 删除异常值[重复]

如何获得熊猫数据框中一行的百分位数?

删除数据框中列的每个因子的异常值

如何从熊猫数据框中的列中删除字符串值