Pandas中的数据透视表小计

10

我有以下数据:

Employee    Account Currency    Amount  Location
Test 2      Basic   USD         3000    Airport
Test 2      Net     USD         2000    Airport
Test 1      Basic   USD         4000    Town
Test 1      Net     USD         3000    Town
Test 3      Basic   GBP         5000    Town
Test 3      Net     GBP         4000    Town

我可以通过以下方式成功转变:

import pandas as pd
table = pd.pivot_table(df, values=['Amount'], index=['Location', 'Employee'], columns=['Account', 'Currency'], fill_value=0, aggfunc=np.sum, dropna=True)

输出:

                      Amount                  
Account            Basic         Net      
Currency             GBP   USD   GBP   USD
Location Employee                         
Airport  Test 2        0  3000     0  2000
Town     Test 1        0  4000     0  3000
         Test 3     5000     0  4000     0

如何通过地点实现小计,然后在底部得到一个总计。

                  Amount                  
Account            Basic         Net      
Currency             GBP   USD   GBP   USD
Location Employee                         
Airport  Test 2        0  3000     0  2000
Airport  Total            3000     0  2000  
Town     Test 1        0  4000     0  3000
         Test 3     5000     0  4000     0
Town Total          5000  4000  4000  3000
Grand Total         5000  7000  4000  5000

我尝试按照这里的方法,但它没有给出想要的输出结果。谢谢。


仅使用pandas吗? - Chiheb Nexus
我稍后会处理这个问题,但这个链接可能有帮助:https://dev59.com/J5nga4cB1Zd3GeqPet_3#38964596。 - piRSquared
2个回答

23

您的数据透视表

table = pd.pivot_table(df, values=['Amount'],
                       index=['Location', 'Employee'],
                       columns=['Account', 'Currency'],
                       fill_value=0, aggfunc=np.sum, dropna=True, )
print(table)

                  Amount                  
Account            Basic         Net      
Currency             GBP   USD   GBP   USD
Location Employee                         
Airport  Test 2        0  3000     0  2000
Town     Test 1        0  4000     0  3000
         Test 3     5000     0  4000     0

pandas.concat

pd.concat([
    d.append(d.sum().rename((k, 'Total')))
    for k, d in table.groupby(level=0)
]).append(table.sum().rename(('Grand', 'Total')))


                  Amount                  
Account            Basic         Net      
Currency             GBP   USD   GBP   USD
Location Employee                         
Airport  2             0  3000     0  2000
         Total         0  3000     0  2000
Town     1             0  4000     0  3000
         3          5000     0  4000     0
         Total      5000  4000  4000  3000
Grand    Total      5000  7000  4000  5000

旧答案

供后人参考

建立小计


tab_tots = table.groupby(level='Location').sum()
tab_tots.index = [tab_tots.index, ['Total'] * len(tab_tots)]
print(tab_tots)

               Amount                  
Account         Basic         Net      
Currency          GBP   USD   GBP   USD
Location                               
Airport  Total      0  3000     0  2000
Town     Total   5000  4000  4000  3000

全部在一起

pd.concat(
    [table, tab_tots]
).sort_index().append(
    table.sum().rename(('Grand', 'Total'))
)

enter image description here


如果我在行上有更多的索引,我该怎么做? - Clayton Tosatti
1
你如何做到相同的事情,但确保每个“位置”的“总计”是底部行? 在这种情况下,它可以正常工作,因为“测试”在“总计”之前,但如果例如是“Zest”,我不知道这将如何工作。 - Kyle

3
这里有两行代码可以完成任务。由于存在多级索引,loc方法允许按索引子集化行,因此我在左侧为行插入点提供了一个元组。如果不使用元组,使用'Town'将拉出索引的所有对应级别。
在第二行中,我必须从DataFrame中删除最后一行,并使用其形状属性来实现这一点。
In[1]:
table.loc[('Town Total', ''),:] = table.loc['Town'].sum()
table.loc[('Grand Total', ''),:] = table.iloc[:(table.shape[0]-1), :].sum()

In[2]:
table

Out[2]: 
                     Amount                  
Account               Basic         Net      
Currency                GBP   USD   GBP   USD
Location    Employee                         
Airport     2             0  3000     0  2000
Town        1             0  4000     0  3000
            3          5000     0  4000     0
Town Total             5000  4000  4000  3000
Grand Total            5000  7000  4000  5000

只是想说这绝对太棒了! - YGA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接