首页 > 解决方案 > 将 .mean() 应用于具有条件的分组数据

问题描述

我有一个df看起来像这样的:

Day         Country         Type        Product         Cost        

Mon         US              1           a1              0
Mon         US              2           a1              5
Mon         US              3           a1              6
Mon         CA              1           a1              8
Mon         CA              2           a1              0
Mon         CA              3           a1              1

我正在努力做到这一点:

Day         Country         Type        Product         Cost        Average

Mon         US              1           a1              0           (5+6)/2
Mon         US              2           a1              5           (5+6)/2
Mon         US              3           a1              6           (5+6)/2
Mon         CA              1           a1              8           (8+1)/2
Mon         CA              2           a1              0           (8+1)/2
Mon         CA              3           a1              1           (8+1)/2

这个想法是将其分组CountryProduct获得平均成本,但取其Costs所在的位置>0

我试过的:

np.where(df['Cost']>0, df.loc[df.groupby(['Country','Product'])]['Cost'].mean())

但我得到:

ValueError:无法使用多维键进行索引

将内置函数(如.mean(), max(), etc带有过滤器的分组熊猫数据框)应用到最佳实践解决方案是什么?

标签: pythonpandas

解决方案


第一个想法是替换0NaNs ,然后使用GroupBy.transformwith mean,默认省略缺失值:

print (df.assign(new = df['Cost'].where(df['Cost'] > 0)))
   Day Country  Type Product  Cost  new
0  Mon      US     1      a1     0  NaN
1  Mon      US     2      a1     5  5.0
2  Mon      US     3      a1     6  6.0
3  Mon      CA     1      a1     8  8.0
4  Mon      CA     2      a1     0  NaN
5  Mon      CA     3      a1     1  1.0


df['Average'] = (df.assign(new = df['Cost'].where(df['Cost'] > 0))
                   .groupby(['Country','Product'])['new']
                   .transform('mean'))
print (df)
   Day Country  Type Product  Cost  Average
0  Mon      US     1      a1     0      5.5
1  Mon      US     2      a1     5      5.5
2  Mon      US     3      a1     6      5.5
3  Mon      CA     1      a1     8      4.5
4  Mon      CA     2      a1     0      4.5
5  Mon      CA     3      a1     1      4.5

或首先过滤、聚合mean并分配回DataFrame.join

s = df[df["Cost"] > 0].groupby(['Country','Product'])['Cost'].mean().rename('Average')
df = df.join(s, on=['Country','Product'])
print (df)
   Day Country  Type Product  Cost  Average
0  Mon      US     1      a1     0      5.5
1  Mon      US     2      a1     5      5.5
2  Mon      US     3      a1     6      5.5
3  Mon      CA     1      a1     8      4.5
4  Mon      CA     2      a1     0      4.5
5  Mon      CA     3      a1     1      4.5

推荐阅读