【问题标题】:Replace values based on multiple conditions with groupby mean in Pandas在 Pandas 中用 groupby mean 替换基于多个条件的值
【发布时间】:2019-11-05 21:45:33
【问题描述】:

假设我有一个如下的数据框:

df = pd.DataFrame({'date': pd.date_range(start='2013-01-01', periods=6, freq='M'), 
                   'value': [3, 3.5, -5, 2, 7, 6.8], 'type': ['a', 'a', 'a', 'b', 'b', 'b']})
df['pct'] = df.groupby(['type'])['value'].pct_change()

输出:

        date  value type       pct
0 2013-01-31    3.0    a       NaN
1 2013-02-28    3.5    a  0.166667
2 2013-03-31   -5.0    a -2.428571
3 2013-04-30    2.0    b       NaN
4 2013-05-31    7.0    b  2.500000
5 2013-06-30    6.8    b -0.028571

我想替换大于0.2或小于-0.2pct值,然后用groupbytypemeans替换它们。

我尝试通过以下方式解决此问题:首先,将“异常值”替换为额外值 -999,然后将它们替换为 groupby 输出,这就是我所做的:

df.loc[df['pct'] >= 0.2, 'pct'] = -999
df.loc[df['pct'] <= -0.2, 'pct'] = -999

df["pct"] = df.groupby(['type'])['pct'].transform(lambda x: x.replace(-999, x.mean()))

但显然,这不是解决这个问题的最佳方案,结果也不正确:

        date  value type         pct
0 2013-01-31    3.0    a         NaN
1 2013-02-28    3.5    a    0.166667
2 2013-03-31   -5.0    a -499.416667
3 2013-04-30    2.0    b         NaN
4 2013-05-31    7.0    b -499.514286
5 2013-06-30    6.8    b   -0.028571

预期的结果应该是这样的:

        date  value type       pct
0 2013-01-31    3.0    a       NaN
1 2013-02-28    3.5    a  0.166667
2 2013-03-31   -5.0    a    -1.130
3 2013-04-30    2.0    b       NaN
4 2013-05-31    7.0    b  2.500000
5 2013-06-30    6.8    b      1.24

我做错了什么?再次感谢您的帮助。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    相反,您可以使用Series.between 并在GroupBy.transformmean 中设置pct 中的值和mean

    mask = df['pct'].between(-0.2, 0.2)
    df.loc[mask, 'pct'] = df.groupby('type')['pct'].transform('mean').values
    print (df)
            date  value type       pct
    0 2013-01-31    3.0    a       NaN
    1 2013-02-28    3.5    a -1.130952
    2 2013-03-31   -5.0    a -2.428571
    3 2013-04-30    2.0    b       NaN
    4 2013-05-31    7.0    b  2.500000
    5 2013-06-30    6.8    b  1.235714
    

    替代解决方案是使用numpy.where:

    mask = df['pct'].between(-0.2, 0.2)
    df['pct'] = np.where(mask, df.groupby('type')['pct'].transform('mean'), df['pct'])
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 2018-10-29
    • 2019-04-10
    • 2022-09-23
    • 2020-10-10
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多