【问题标题】:Remove outliers from pandas dataframe python从熊猫数据框python中删除异常值
【发布时间】:2018-01-09 17:23:29
【问题描述】:

我有一个使用 pandas 创建数据框的代码

import pandas as pd
import numpy as np

x = (g[0].time[:111673])
y = (g[0].data.f[:111673])
df = pd.DataFrame({'Time': x, 'Data': y})
#df

打印出来:

          Data          Time
0        -0.704239      7.304021
1        -0.704239      7.352021
2        -0.704239      7.400021
3        -0.704239      7.448021
4        -0.825279      7.496021

这很好,但我知道我想删除这些数据中的异常值,所以我在下面创建了这个数据框来指出它们:

newdf = df.copy()
Data = newdf.groupby('Data')
newdf[np.abs(newdf.Data-newdf.Data.mean())<=(3*newdf.Data.std())]
newdf['Outlier'] = Data.transform( lambda x: abs(x-x.mean()) > 1.96*x.std() )
#newdf

打印出来:

             Data          Time  Outlier
0        -0.704239      7.304021    False
1        -0.704239      7.352021    False
2        -0.704239      7.400021    False
3        -0.704239      7.448021    False
4        -0.825279      7.496021    False

在我的数据示例中,您看不到它,但可能有 300 个异常值,我想删除它们而不弄乱原始数据框,然后将它们一起绘制为压缩。 我的问题是这样的:那么,我怎样才能消除真实的异常值,而不是打印出 false/true 呢?所以我最终可以将它们绘制在同一张图中进行比较。

我已经尝试过的代码:

newdf[np.abs(newdf.Data-newdf.Data.mean())<=(1.96*newdf.Data.std())]

newdf = df.copy()
def replace_outliers_with_nan(df, stdvs):
    newdf=pd.DataFrame()
    for i, col in enumerate(df.sites.unique()):
        df = pd.DataFrame(df[df.sites==col])
        idx = [np.abs(df-df.mean())<=(stdvs*df.std())] 
        df[idx==False]=np.nan  
        newdf[col] = df
    return newdf

这两个都不起作用,它们返回的数据点数量与我的原始数据帧相同,但是我知道如果它删除了异常值,点的数量将少于原始数据。

【问题讨论】:

    标签: python pandas outliers


    【解决方案1】:

    看来您需要boolean indexing~ 来反转条件,因为只需要过滤异常值行(并删除异常值):

    df1 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
    print (df1)
           Data      Time
    0 -0.704239  7.304021
    1 -0.704239  7.352021
    2 -0.704239  7.400021
    3 -0.704239  7.448021
    4 -0.825279  7.496021
    

    【讨论】:

    • 当我尝试你的答案时,我得到一个值错误:raise ValueError(msg.format(dtype=dt)) ValueError: Boolean array expected for the condition, not float64
    • 什么返回 print (df.groupby('Data').transform( lambda x: abs(x-x.mean()) &gt; 1.96*x.std())) ?不是True and False 系列?
    • 我发现问题,你需要.values 来将Series转换为numpy数组。
    • 你的措辞让我有点困惑。是的,print (df.groupby('Data').transform( lambda x: abs(x-x.mean()) &gt; 1.96*x.std())) 为我的“时间”列返回一个 True or False 系列,而“数据”列则没有。但我已经用Data = newdf.groupby('Data') newdf[np.abs(newdf.Data-newdf.Data.mean())&lt;=(3*newdf.Data.std())] newdf['Outlier'] = Data.transform( lambda x: abs(x-x.mean()) &gt; 1.96*x.std() ) 做到了,我希望从“数据”列中删除异常值。
    • 好的,谢谢!抱歉,我在上次发表评论之前没有看到您的编辑。
    猜你喜欢
    • 1970-01-01
    • 2018-02-24
    • 2020-07-26
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多