Pandas Pivot表行小计

bal*_*oth 38 python pivot-table pandas

我正在使用Pandas 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
Run Code Online (Sandbox Code Playgroud)

我如何组合每个州的小计?

State   City  SalesToday  SalesMTD  SalesYTD
  stA    ALL          50       900      2100
  stA    ctA          20       400      1000
  stA    ctB          30       500      1100
Run Code Online (Sandbox Code Playgroud)

我尝试使用数据透视表,但我只能在列中使用小计

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

我可以使用数据透视表在excel上实现这一点.

Wes*_*ney 45

如果您将State和City都放在行中,则会获得单独的边距.重塑并获得您追求的桌子:

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
Run Code Online (Sandbox Code Playgroud)

我承认这并不完全是显而易见的.

  • 如果我们有值=,这是有效的,如果从列创建列= ...那么只有一个"全部"列. (3认同)
  • @wes-mckinney 对于 pandas 0.25.1 版本,“rows”不是参数。我指定了 3 列索引,但输出仅返回总计,而不返回索引列的小计。 (3认同)

Rut*_*ies 21

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

让我们先做一些样本数据:

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)
Run Code Online (Sandbox Code Playgroud)

然后应用groupby函数并添加一列City:

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
Run Code Online (Sandbox Code Playgroud)

我们可以使用append将原始数据附加到求和的df:

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
Run Code Online (Sandbox Code Playgroud)

我添加了set_index和sort_index,使它看起来更像你的示例输出,它不是获取结果所必需的.


小智 6

我认为这个小计示例代码是你想要的(类似于excel小计)

我假设您希望按列A,B,C,D分组,而不是E的计数列值

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

输出:

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
Run Code Online (Sandbox Code Playgroud)