执行groupby求和后保留multindex列结构

时间:2019-12-27 08:45:21

标签: python pandas

我有一个三级多索引列。在最低级别,我要添加一个小计列。

因此,在这里的示例中,我希望有一个新列zone: dayperson:davefind:'subtotal',其值= 49 + 27 + 63 = 138。 zoneperson的所有其他组合类似。 enter image description here

cols = pd.MultiIndex.from_product([['day', 'night'], ['dave', 'matt', 'mike'], ['gems', 'rocks', 'paper']])
rows = pd.date_range(start='20191201', periods=5, freq="d")
data = np.random.randint(0, high=100,size=(len(rows), len(cols)))
xf = pd.DataFrame(data, index=rows, columns=cols)
xf.columns.names = ['zone', 'person', 'find']

我可以使用xf.groupby(level=[0,1], axis="columns").sum()生成正确的小计数据,但是随后我丢失了列的find级别,它只留下了zoneperson级别。我需要称为subtotal的第三级列,以便可以join并返回原始的xf数据帧。但是我想不出一个很好的pythonic方式,可以将multi-dex添加到第三级。

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以先使用sum,然后再将MultiIndex.from_product用于新级别:

df = xf.sum(level=[0,1], axis="columns")

df.columns = pd.MultiIndex.from_product(df.columns.levels + [['subtotal']])
print (df)
                day                      night                  
               dave     matt     mike     dave     matt     mike
           subtotal subtotal subtotal subtotal subtotal subtotal
2019-12-01       85       99      163      210       93      252
2019-12-02       38      113      101      211      110      135
2019-12-03      145       75      122      181      165      176
2019-12-04      220      184      173      179      134      192
2019-12-05      126       77       29      184      178      199

然后由concatDataFrame.sort_index一起加入:

df = pd.concat([xf, df], axis=1).sort_index(axis=1)
print (df)
zone        day                                                            \
person     dave                      matt                      mike         
find       gems paper rocks subtotal gems paper rocks subtotal gems paper   
2019-12-01   33    96    24      153   34    89    90      213   15    51   
2019-12-02   74    48    61      183   94    83     2      179   75     4   
2019-12-03   88    85    51      224   65     3    52      120   95    80   
2019-12-04   43    28    60      131   43    14    77      134   88    54   
2019-12-05   41    72    44      157   63    77    37      177    8    66   

zone        ... night                                                      \
person      ...  dave          matt                      mike               
find        ... rocks subtotal gems paper rocks subtotal gems paper rocks   
2019-12-01  ...    24      102   19    49     4       72   43    57    92   
2019-12-02  ...    90      206   96    55    92      243   75    58    68   
2019-12-03  ...    29      182   11    90    85      186    9    20    46   
2019-12-04  ...    30       84   25    55    89      169   98    41    85   
2019-12-05  ...    73      167   52    90    49      191   51    80    37   

zone                 
person               
find       subtotal  
2019-12-01      192  
2019-12-02      201  
2019-12-03       75  
2019-12-04      224  
2019-12-05      168  

[5 rows x 24 columns]