在 Pandas 中处理子索引

Manipulating subindex in Pandas

让我们生成以下内容 pandas.DataFrame:

np.random.seed(42)
mi = pd.MultiIndex(levels=[[0, 1, 2, 3, 4, 5, 6], [0, 1]],
             labels=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6], 
                     [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]],
             names=['day_of_week', 'cat'])
X = pd.DataFrame(np.random.randint(1,100,size=14), mi, ['count'])

我想添加一列,用于保存每个 (day_of_week, cat) 的值与 day_of_week 的两个值之和之间的比率。例如,所需列的前两行为:[52/(52+93), 93/(52+93),...]

我知道如何计算每天的总和:X.sum(level=0),但我不知道如何继续。我可以迭代并循环出路,但这不会是 pythonic。

Series 需要除以 div with groupby by level day_of_week with transform 与原始 df 相同 index:

print (X.groupby(level='day_of_week')['count'].transform('sum'))
day_of_week  cat
0            0      145
             1      145
1            0       87
             1       87
2            0       82
             1       82
3            0      170
             1      170
4            0      150
             1      150
5            0      112
             1      112
6            0       25
             1       25
Name: count, dtype: int32
X['ratio'] = X['count'].div(X.groupby(level='day_of_week')['count'].transform('sum'))
print (X)
                 count     ratio
day_of_week cat                 
0           0       52  0.358621
            1       93  0.641379
1           0       15  0.172414
            1       72  0.827586
2           0       61  0.743902
            1       21  0.256098
3           0       83  0.488235
            1       87  0.511765
4           0       75  0.500000
            1       75  0.500000
5           0       88  0.785714
            1       24  0.214286
6           0        3  0.120000
            1       22  0.880000

在上一个 pandas 版本中可以省略 level:

X['ratio'] = X['count'].div(X.groupby('day_of_week')['count'].transform('sum'))