如何 pandas groupby 和 pivot_table 使数据透视表看起来像 Excel 的

How to pandas groupby and pivot_table to have pivto tables look like Excel's

我有这个数据框,我必须把它变成一个枢轴 table。没问题。 Pandas 提供 pivot / pivot_table 允许创建漂亮的 pivot tables 但有一些 Excel 的功能我似乎无法复制。

哪些?中途聚合(在 division_sac_ac 中看到的聚合总和)并通过

获得
slice_ac = df.groupby(by='ac').sum()
slice_sac = df.groupby(by='sac').sum()

如何整合 3 个(枢轴,slice_ac,slice_sac)对象?

编辑:部分结果但仍然不令人满意(部分原因是我可以整合 slice_sac 但不能整合 slice_ac - 通常它的审美距离 excel):

table_df = pd.pivot_table(df, index=['ac','sac'], values='value', columns=['name'], aggfunc=[np.sum], margins=True)
print(table_df.stack(['name']))

产生:

                        sum
ac     sac    name         
bond   Corp   omega    0.05
              All      0.05
       Govt   lambda   0.05
              rho      0.20
              All      0.25
equity Europe alfa     0.05
              beta     0.05
              gamma    0.10
              All      0.20
       US     epsilon  0.20
              All      0.20
All           alfa     0.05
              beta     0.05
              epsilon  0.20
              gamma    0.10
              lambda   0.05
              omega    0.05
              rho      0.20
              All      0.70

示例:

import pandas as pd
import numpy as np

division_sac_ac = {'equity': ['Europe', 'US'], 'bond': ['Corp', 'Govt']}

df = pd.DataFrame.from_dict({'record_1': ['alfa', 'Europe', 'equity', 0.05],
'record_2': ['beta', 'Europe', 'equity', 0.05],
'record_3': ['gamma', 'Europe', 'equity', 0.1],
'record_4': ['epsilon', 'US', 'equity', 0.2],
'record_5': ['rho', 'Govt', 'bond', 0.2],
'record_6': ['lambda', 'Govt', 'bond', 0.05],
'record_7': ['omega', 'Corp', 'bond', 0.05], }, orient='index')

df.columns = ['name', 'sac', 'ac', 'value']

table_df = pd.pivot_table(df, index=['ac','sac','name'], values='value', aggfunc=[np.sum])

slice_ac = df.groupby(by='ac').sum()
slice_sac = df.groupby(by='sac').sum()

print(table_df)
print(slice_ac)
print(slice_sac)

table_df 完成了这项工作,但我还想整合中途结果 (slice_ac, slice_sac),如下图所示:

而我的输出更像是:

                        sum
ac     sac    name         
bond   Corp   omega    0.05
       Govt   lambda   0.05
              rho      0.20
equity Europe alfa     0.05
              beta     0.05
              gamma    0.10
       US     epsilon  0.20
        value
ac           
bond      0.3
equity    0.4
        value
sac          
Corp     0.05
Europe   0.20
Govt     0.25
US       0.20

您可以通过将空值(或像 'subtotal' 这样的占位符值)作为聚合列的索引值来连接 table_dfslice_acslice_sac,例如

slice_ac = table_df.groupby(level=0).sum()
slice_sac = table_df.groupby(level=[0, 1]).sum()

slice_ac.index = pd.MultiIndex.from_tuples([(i, '', '') for i in slice_ac.index])
slice_sac.index = pd.MultiIndex.from_tuples([(i, j, '') for i, j in slice_sac.index])

pd.concat([table_df, slice_ac, slice_sac]).sort()

会输出

                       sum
ac     sac    name
bond                   0.30
       Corp            0.05
              omega    0.05
       Govt            0.25
              lambda   0.05
              rho      0.20
equity                 0.40
       Europe          0.20
              alfa     0.05
              beta     0.05
              gamma    0.10
       US              0.20
              epsilon  0.20