利用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
很幸運能夠有這麼多好用的方法,大大簡化了數據分組分析的過程。