【问题标题】:Pandas dataframe - remove outliers [duplicate]熊猫数据框 - 删除异常值[重复]
【发布时间】:2018-02-24 23:14:46
【问题描述】:

给定一个 pandas 数据框,我想根据其中一列排除与异常值(Z 值 = 3)相对应的行。

数据框如下所示:

df.dtypes
_id                   object
_index                object
_score                object
_source.address       object
_source.district      object
_source.price        float64
_source.roomCount    float64
_source.size         float64
_type                 object
sort                  object
priceSquareMeter     float64
dtype: object

对于线路:

dff=df[(np.abs(stats.zscore(df)) < 3).all(axis='_source.price')]

引发以下异常:

-------------------------------------------------------------------------    
TypeError                                 Traceback (most recent call last)
<ipython-input-68-02fb15620e33> in <module>()
----> 1 dff=df[(np.abs(stats.zscore(df)) < 3).all(axis='_source.price')]

/opt/anaconda3/lib/python3.6/site-packages/scipy/stats/stats.py in zscore(a, axis, ddof)
   2239     """
   2240     a = np.asanyarray(a)
-> 2241     mns = a.mean(axis=axis)
   2242     sstd = a.std(axis=axis, ddof=ddof)
   2243     if axis and mns.ndim < a.ndim:

/opt/anaconda3/lib/python3.6/site-packages/numpy/core/_methods.py in _mean(a, axis, dtype, out, keepdims)
     68             is_float16_result = True
     69 
---> 70     ret = umr_sum(arr, axis, dtype, out, keepdims)
     71     if isinstance(ret, mu.ndarray):
     72         ret = um.true_divide(

TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

以及返回值

np.isreal(df['_source.price']).all()

True

为什么会出现上述异常,如何排除异常值?

【问题讨论】:

    标签: python pandas scipy


    【解决方案1】:

    如果想使用给定数据集的 Interquartile Range(即 IQR,如下面的 Wikipedia image 所示)(Ref):

    def Remove_Outlier_Indices(df):
        Q1 = df.quantile(0.25)
        Q3 = df.quantile(0.75)
        IQR = Q3 - Q1
        trueList = ~((df < (Q1 - 1.5 * IQR)) |(df > (Q3 + 1.5 * IQR)))
        return trueList
    

    基于上述消除函数,可以根据数据集的统计内容得到离群值的子集:

    # Arbitrary Dataset for the Example
    df = pd.DataFrame({'Data':np.random.normal(size=200)})
    
    # Index List of Non-Outliers
    nonOutlierList = Remove_Outlier_Indices(df)
    
    # Non-Outlier Subset of the Given Dataset
    dfSubset = df[nonOutlierList]
    

    【讨论】:

    • 正是我想要的。竖起大拇指。谢谢。
    • 如果想同时应用到多个定量列(Data1、Data2等),添加.all(1):dfSubset = df[nonOutlierList.all(1)]
    【解决方案2】:

    我相信您可以使用异常值创建一个布尔过滤器,然后选择它的反面。

    outliers = stats.zscore(df['_source.price']).apply(lambda x: np.abs(x) == 3)
    df_without_outliers = df[~outliers]
    

    【讨论】:

      【解决方案3】:

      遇到此类问题时使用此布尔值:

      df=pd.DataFrame({'Data':np.random.normal(size=200)})  #example 
      df[np.abs(df.Data-df.Data.mean())<=(3*df.Data.std())] #keep only the ones that are within +3 to -3 standard deviations in the column 'Data'.
      df[~(np.abs(df.Data-df.Data.mean())>(3*df.Data.std()))] #or the other way around
      

      【讨论】:

      • AttributeError: 'DataFrame' object has no attribute 'Data'
      • @Nairum Data 是被访问的df 的列。需要对其进行更改以适合您要在其中检测异常值的特定 DataFrame 的实际列。
      猜你喜欢
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      相关资源
      最近更新 更多