【问题标题】:Transforming outliers in Pandas DataFrame using .apply, .applymap, .groupby使用 .apply、.applymap、.groupby 转换 Pandas DataFrame 中的异常值
【发布时间】:2015-09-09 10:13:25
【问题描述】:

我正在尝试将 pandas DataFrame 对象转换为一个新对象,该对象包含基于一些简单阈值的点分类:

  • 如果该点为NaN,则值转换为0
  • 如果该点为负数或 0,则值转换为 1
  • 如果值超出基于整个列的特定条件,则转换为 2
  • 否则值为3

这是一个非常简单的独立示例:

import pandas as pd
import numpy as np

df=pd.DataFrame({'a':[np.nan,1000000,3,4,5,0,-7,9,10],'b':[2,3,-4,5,6,1000000,7,9,np.nan]})

print(df)

到目前为止创建的转换过程:

#Loop through and find points greater than the mean -- in this simple example, these are the 'outliers'
outliers = pd.DataFrame()
for datapoint in df.columns:
    tempser = pd.DataFrame(df[datapoint][np.abs(df[datapoint]) > (df[datapoint].mean())])
    outliers = pd.merge(outliers, tempser, right_index=True, left_index=True, how='outer')

outliers[outliers.isnull() == False] = 2


#Classify everything else as "3"
df[df > 0] = 3

#Classify negative and zero points as a "1"
df[df <= 0] = 1

#Update with the outliers
df.update(outliers)

#Everything else is a "0"
df.fillna(value=0, inplace=True)

导致:

我尝试使用.applymap() 和/或.groupby() 来加快进程,但没有成功。我在 this answer 中找到了一些指导,但是,当您不在 pandas 列中分组时,我仍然不确定 .groupby() 是否有用。

【问题讨论】:

    标签: python numpy pandas outliers


    【解决方案1】:

    这是异常值部分的替换。在我的计算机上处​​理您的样本数据大约快 5 倍。

    >>> pd.DataFrame( np.where( np.abs(df) > df.mean(), 2, df ), columns=df.columns )
    
        a   b
    0 NaN   2
    1   2   3
    2   3  -4
    3   4   5
    4   5   6
    5   0   2
    6  -7   7
    7   9   9
    8  10 NaN
    

    您也可以使用 apply 来执行此操作,但它会比 np.where 方法慢(但与您当前所做的速度大致相同),但要简单得多。这可能是一个很好的例子,说明当您关心速度时,为什么应该始终避免使用apply

    >>> df[ df.apply( lambda x: abs(x) > x.mean() ) ] = 2
    

    你也可以这样做,比apply快但比np.where慢:

    >>> mask = np.abs(df) > df.mean()
    >>> df[mask] = 2
    

    当然,这些东西并不总是线性扩展,因此请在您的真实数据上对其进行测试,看看比较结果如何。

    【讨论】:

    • 对于异常值部分,我只希望值仅在满足其列的条件语句时替换为2不是整个数据框——我认为您的解决方案使用整个数据框?
    • @cmiller8 不,它是每列。键入df.mean(),您会看到它为每列提供了一个平均值。你也可以尝试一些不同的样本数据来测试它。
    • 你是对的!而且你的方法比 10k 列、25k 行数据帧快 300 倍
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多