在groupby之后为唯一多索引值的组合填充零值

时间:2017-06-27 18:29:01

标签: python pandas

为了更好地解决问题,我们假设我有一个拥有3个独特客户的商店,而我的数据框包含我的客户每周购买的工作日,名称和付费价格。

     name  price  weekday
0    Paul  18.44        0
1   Micky   0.70        0
2   Sarah   0.59        0
3   Sarah   0.27        1
4    Paul   3.45        2
5   Sarah  14.03        2
6    Paul  17.21        3
7   Micky   5.35        3
8   Sarah   0.49        4
9   Micky  17.00        4
10   Paul   2.62        4
11  Micky  17.61        5
12  Micky  10.63        6

我想获得的信息是每个工作日每位唯一客户的平均价格。我在类似情况下经常做的是用sum对几列进行分组,然后取一列子集的平均值。

df = df.groupby(['name','weekday']).sum()



              price
name  weekday       
Micky 0         0.70
      3         5.35
      4        17.00
      5        17.61
      6        10.63
Paul  0        18.44
      2         3.45
      3        17.21
      4         2.62
Sarah 0         0.59
      1         0.27
      2        14.03
      4         0.49

df = df.groupby(['weekday']).mean()

             price
weekday           
0         6.576667
1         0.270000
2         8.740000
3        11.280000
4         6.703333
5        17.610000
6        10.630000

当然,这仅适用于我所有独特客户每天至少购买一次的情况。 是否有一种优雅的方法可以在第一组之后没有和的唯一索引值之间获得零值?

到目前为止,我的解决方案要么重新索引我根据分组列的唯一值或unstack-fillna-stack的组合创建的多索引,但这两种解决方案并不能真正满足我。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

IIUC,让我们使用unstackfillna然后使用stack

df_out = df.groupby(['name','weekday']).sum().unstack().fillna(0).stack()

输出:

               price
name  weekday       
Micky 0         0.70
      1         0.00
      2         0.00
      3         5.35
      4        17.00
      5        17.61
      6        10.63
Paul  0        18.44
      1         0.00
      2         3.45
      3        17.21
      4         2.62
      5         0.00
      6         0.00
Sarah 0         0.59
      1         0.27
      2        14.03
      3         0.00
      4         0.49
      5         0.00
      6         0.00

df_out.groupby('weekday').mean()

输出:

            price
weekday          
0        6.576667
1        0.090000
2        5.826667
3        7.520000
4        6.703333
5        5.870000
6        3.543333

答案 1 :(得分:1)

我认为您可以使用pivot_table一次执行所有步骤。我不确定你想要什么,但pivot_table的默认聚合是平均值。您可以将其更改为' sum'。

df1 = df.pivot_table(index='name', columns='weekday', values='price', 
                     fill_value=0, aggfunc='sum')

weekday      0     1      2      3      4      5      6
name                                                   
Micky     0.70  0.00   0.00   5.35  17.00  17.61  10.63
Paul     18.44  0.00   3.45  17.21   2.62   0.00   0.00
Sarah     0.59  0.27  14.03   0.00   0.49   0.00   0.00

然后取每列的平均值。

df1.mean()

weekday
0    6.576667
1    0.090000
2    5.826667
3    7.520000
4    6.703333
5    5.870000
6    3.543333