web-dev-qa-db-fra.com

Pandas Tableaux croisés dynamiques sous-totaux de ligne

J'utilise Pandas 0.10.1

Compte tenu de ce Dataframe:

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

Comment regrouper des sous-totaux par état?

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

J'ai essayé avec un tableau croisé dynamique mais je ne peux avoir que des sous-totaux dans les colonnes

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

Je peux y parvenir sur Excel, avec un tableau croisé dynamique.

37
balsagoth

Si vous ne mettez pas State et City dans les lignes, vous obtiendrez des marges distinctes. Remodelez et vous obtenez la table que vous recherchez:

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

J'avoue que ce n'est pas totalement évident.

44
Wes McKinney

Vous pouvez obtenir les valeurs résumées en utilisant groupby () dans la colonne État.

Permet de faire quelques exemples de données en premier:

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)

Ensuite, appliquez la fonction groupby et ajoutez une colonne Ville:

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

Nous pouvons ajouter les données d'origine au df additionné en utilisant append:

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

J'ai ajouté set_index et sort_index pour le faire ressembler davantage à votre exemple de sortie, ce n'est pas strictement nécessaire pour obtenir les résultats.

20
Rutger Kassies

Je pense que cet exemple de code de sous-total est ce que vous voulez (similaire au sous-total Excel)

Je suppose que vous voulez grouper par les colonnes A, B, C, D, puis compter la valeur de la colonne E

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

sortie:

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
6
hs moon

Celui-ci, ça va ?

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

enter image description here

1
Richard Mao