2013-03-22 64 views
30

我用熊猫0.10.1熊猫透视表行小计

考虑到这个数据帧:

Date  State City SalesToday SalesMTD SalesYTD 
20130320  stA ctA   20  400  1000 
20130320  stA ctB   30  500  1100 
20130320  stB ctC   10  500  900 
20130320  stB ctD   40  200  1300 
20130320  stC ctF   30  300  800 

怎么能每状态i组小计?

State City SalesToday SalesMTD SalesYTD 
    stA ALL   50  900  2100 
    stA ctA   20  400  1000 
    stA ctB   30  500  1100 

我试着用透视表,但我只能有小计列

table = pivot_table(df, values=['SalesToday', 'SalesMTD','SalesYTD'],\ 
        rows=['State','City'], aggfunc=np.sum, margins=True) 

我可以在Excel中实现这一点,与数据透视表。

回答

36

如果您将状态和城市都放在行中,您将获得单独的边距。重塑,你得到你后表:

In [10]: table = pivot_table(df, values=['SalesToday', 'SalesMTD','SalesYTD'],\ 
        rows=['State'], cols=['City'], aggfunc=np.sum, margins=True) 


In [11]: table.stack('City') 
Out[11]: 
      SalesMTD SalesToday SalesYTD 
State City         
stA All  900   50  2100 
     ctA  400   20  1000 
     ctB  500   30  1100 
stB All  700   50  2200 
     ctC  500   10  900 
     ctD  200   40  1300 
stC All  300   30  800 
     ctF  300   30  800 
All All  1900   130  5100 
     ctA  400   20  1000 
     ctB  500   30  1100 
     ctC  500   10  900 
     ctD  200   40  1300 
     ctF  300   30  800 

我承认这并不完全明显。

+3

这个工作如果我们有值=,如果列是从列创建= ...将只有一个“全部”列。 – Winand 2015-05-29 10:31:47

18

您可以通过在State列上使用groupby()来获取汇总值。

让我们先作一些样本数据:通过使用附加

dfsum = df.groupby('State', as_index=False).sum() 
dfsum['City'] = 'All' 

print dfsum 

    State SalesToday SalesMTD SalesYTD City 
0 stA   50  900  2100 All 
1 stB   50  700  2200 All 
2 stC   30  300  800 All 

我们可以在原始数据追加到总结DF:

import pandas as pd 
import StringIO 

incsv = StringIO.StringIO("""Date,State,City,SalesToday,SalesMTD,SalesYTD 
20130320,stA,ctA,20,400,1000 
20130320,stA,ctB,30,500,1100 
20130320,stB,ctC,10,500,900 
20130320,stB,ctD,40,200,1300 
20130320,stC,ctF,30,300,800""") 

df = pd.read_csv(incsv, index_col=['Date'], parse_dates=True) 

然后应用GROUPBY功能,并添加一列城市:

dfsum.append(df).set_index(['State','City']).sort_index() 

print dfsum 

      SalesMTD SalesToday SalesYTD 
State City         
stA All  900   50  2100 
     ctA  400   20  1000 
     ctB  500   30  1100 
stB All  700   50  2200 
     ctC  500   10  900 
     ctD  200   40  1300 
stC All  300   30  800 
     ctF  300   30  800 

我加入了set_index和sort_index使它看起来更像是你的榜样输出,它对于获得结果并不是绝对必要的。

0

这个怎么样?

table = pd.pivot_table(data, index=['State'],columns = ['City'],values=['SalesToday', 'SalesMTD','SalesYTD'],\ 
         aggfunc=np.sum, margins=True) 

enter image description here

1

我觉得这个小计示例代码是你想要的(类似于擅长小计)

我假设你按列A,B,C,d,比数要组è的列值

main_df.groupby(['A', 'B', 'C']).apply(lambda sub_df: sub_df\ 
     .pivot_table(index=['D'], values=['E'], aggfunc='count', margins=True) 

输出:

A B C D E 
     a 1 
a a a b 2 
     c 2 
    all 5 
     a 3 
b b a b 2 
     c 2 
    all 7 
     a 3 
b b b b 6 
     c 2 
     d 3 
    all 14