天天看點

Pandas分組統計函數:groupby、pivot_table及crosstab

利用python的pandas庫進行資料分組分析十分便捷,其中應用最多的方法包括:groupby、pivot_table及crosstab,以下分别進行介紹。

0、樣例資料

df = DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})
df
#[Out]#       data1     data2 key1 key2
#[Out]# 0  0.439801  1.582861    a  one
#[Out]# 1 -1.388267 -0.603653    a  two
#[Out]# 2 -0.514400 -0.826736    b  one
#[Out]# 3 -1.487224 -0.192404    b  two
#[Out]# 4  2.169966  0.074715    a  one
           

1、分組groupby 

Pandas中最為常用和有效的分組函數。

1)按列分組

注意以下使用groupby()函數生成的group1是一個中間分組變量,為GroupBy類型。

group1 = df.groupby('key1')
group1
#[Out]# <pandas.core.groupby.DataFrameGroupBy object at 0x0000000009CA5780>
           

既可依據單個列名’key1’進行為分組,也可依據多個列名['key1','key2']進行分組。

group2 = df.groupby(['key1','key2'])
group2
#[Out]# <pandas.core.groupby.DataFrameGroupBy object at 0x0000000009CB4128>
           

使用推導式[x for x in group1]可顯示分組内容。

[x for x in group1]
#[Out]# [('a',       data1     data2 key1 key2
#[Out]#   0  0.439801  1.582861    a  one
#[Out]#   1 -1.388267 -0.603653    a  two
#[Out]#   4  2.169966  0.074715    a  one), 
#[Out]#  ('b',       data1     data2 key1 key2
#[Out]#   2 -0.514400 -0.826736    b  one
#[Out]#   3 -1.487224 -0.192404    b  two)]
           

2)按分組統計

在分組group1、group2上應用size()、sum()、count()等統計函數,能分别統計分組數量、不同列的分組和、不同列的分組數量。

group1.size()
#[Out]# key1
#[Out]# a    3
#[Out]# b    2
#[Out]# dtype: int64
group1.sum()
#[Out]#          data1     data2
#[Out]# key1                    
#[Out]# a     1.221499  1.053922
#[Out]# b    -2.001624 -1.019140
group2.size()
#[Out]# key1  key2
#[Out]# a     one     2
#[Out]#       two     1
#[Out]# b     one     1
#[Out]#       two     1
#[Out]# dtype: int64
group2.count()
#[Out]#            data1  data2
#[Out]# key1 key2              
#[Out]# a    one       2      2
#[Out]#      two       1      1
#[Out]# b    one       1      1
#[Out]#      two       1      1
           

3)應用agg()

對于分組的某一列或者多個列,應用agg(func)可以對分組後的資料應用func函數。例如:用group1['data1'].agg('mean')對分組後的’data1’列求均值。當然也可以推廣到同時作用于多個列和使用多個函數上。

group1['data1'].agg('mean')
#[Out]# key1
#[Out]# a    0.407166
#[Out]# b   -1.000812
#[Out]# Name: data1, dtype: float64
group1['data1'].agg(['mean','sum'])
#[Out]#           mean       sum
#[Out]# key1                    
#[Out]# a     0.407166  1.221499
#[Out]# b    -1.000812 -2.001624
group1['data1','data2'].agg(['mean','sum'])
#[Out]#          data1               data2          
#[Out]#           mean       sum      mean       sum
#[Out]# key1                                        
#[Out]# a     0.407166  1.221499  0.351307  1.053922
#[Out]# b    -1.000812 -2.001624 -0.509570 -1.019140
           

4)應用apply()

apply()不同于agg()的地方在于:前者應用于dataframe的各個列,後者僅作用于指定的列。

df.groupby('key1').apply(mean)
#[Out]#          data1     data2
#[Out]# key1                    
#[Out]# a     0.407166  0.351307
#[Out]# b    -1.000812 -0.509570
df.groupby(['key1','key2']).apply(mean)
#[Out]#               data1     data2
#[Out]# key1 key2                    
#[Out]# a    one   1.304883  0.828788
#[Out]#      two  -1.388267 -0.603653
#[Out]# b    one  -0.514400 -0.826736
#[Out]#      two  -1.487224 -0.192404
           

2、透視表pivot_table 

可以産生類似于excel資料透視表的結果,相當的直覺。

1)分組統計

其中參數index指定“行”鍵,columns指定“列”鍵。

df
#[Out]#       data1     data2 key1 key2
#[Out]# 0  0.439801  1.582861    a  one
#[Out]# 1 -1.388267 -0.603653    a  two
#[Out]# 2 -0.514400 -0.826736    b  one
#[Out]# 3 -1.487224 -0.192404    b  two
#[Out]# 4  2.169966  0.074715    a  one
pd.pivot_table(df, index='key1', columns='key2')
#[Out]#          data1               data2          
#[Out]# key2       one       two       one       two
#[Out]# key1                                        
#[Out]# a     1.304883 -1.388267  0.828788 -0.603653
#[Out]# b    -0.514400 -1.487224 -0.826736 -0.192404
df.pivot_table(['data1'], index='key1',columns='key2')
#[Out]#          data1          
#[Out]# key2       one       two
#[Out]# key1                    
#[Out]# a     1.304883 -1.388267
#[Out]# b    -0.514400 -1.487224
           

2)分項彙總

如果将參數margins設定為True,則可以得到分項總計資料。

df.pivot_table(index='key1',columns='key2', margins=True)
#[Out]#          data1                         data2                    
#[Out]# key2       one       two       All       one       two       All
#[Out]# key1                                                            
#[Out]# a     1.304883 -1.388267  0.407166  0.828788 -0.603653  0.351307
#[Out]# b    -0.514400 -1.487224 -1.000812 -0.826736 -0.192404 -0.509570
#[Out]# All   0.698455 -1.437746 -0.156025  0.276947 -0.398029  0.006956
           

3、交叉表crosstab 

可以按照指定的行和列統計分組頻數,用起來非常友善;當然同樣的功能也可采用groupby實作。

pd.crosstab(df.key1,df.key2, margins=True)
#[Out]# key2  one  two  All
#[Out]# key1               
#[Out]# a       2    1    3
#[Out]# b       1    1    2
#[Out]# All     3    2    5
           

很幸運能夠有這麼多好用的方法,大大簡化了資料分組分析的過程。