2016-07-06 1 views
1

У меня есть этот dataframe, который я должен превратить в сводную таблицу. Нет проблем. Pandas предлагает pivot/pivot_table, которые позволяют создавать красивые сводные таблицы, но есть некоторые особенности Excel, которые я не могу воспроизвести.Как pandas groupby и pivot_table, чтобы таблицы pivto выглядели как Excel's

какие? середине пути агрегаты (суммарные суммирует замеченные в division_sac_ac) и полученный через

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

Как я могу интегрировать 3 (стержень, slice_ac, slice_sac) объекты?

EDIT: частичный результат, но до сих пор не является удовлетворительным (частично потому, что я мог бы интегрировать slice_sac но не slice_ac - и в целом aestetichs всего это милях от первенствует):

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), как показано на рисунке: enter image description here

в то время как мой выход больше похож:

     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 

ответ

1

Вы могли бы concatenate table_df, slice_ac & slice_sac, имея пустые значения (или значение-заполнитель как «subtotal») в качестве значения индекса для агрегированных столбцов, например

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 
+0

отлично! Спасибо – Asher11