前言
“split-apply-combine”(拆分-應用-合併)很好地描述了分組運算的整個過程。
分組運算的第一個階段,pandas對象(無論是Series、DataFrame還是其他的)中的數據會根據所提供的一個或多個鍵被拆分(split)為多組。
拆分操作是在對象的特定軸上執行的。例如,DataFrame可以在其行(axis=0)或列(axis=1)上進行分組。
然後,將一個函數應用(apply)到各個分組併產生一個新值。
最後,所有這些函數的執行結果會被合併(combine)到最終的結果對象中。結果對象的形式一般取決於數據上所執行的操作。
下圖,大致說明了一個簡單的分組聚合過程:
分組鍵
分組鍵可以有多種形式,且類型不必相同:
- 列表或數組,其長度與待分組的軸一樣。
- 表示DataFrame某個列名的值。
- 字典或Series,給出待分組軸上的值與分組名之間的對應關係。
- 函數,用於處理軸索引中的各個標籤。
注意:後三種都只是快捷方式而已,其最終目的仍然是產生一組用於拆分對象的值。
先了解一下表格型數據集(以DataFrame的形式):
<code>In [1]: import numpy as npIn [2]: import pandas as pdIn [3]: from pandas import Series,DataFrameIn [4]: df=DataFrame({'key1':['a','a','b','b','a'], 'key2':['one','two','one','two','one'], 'data1':np.random.randn(5), 'data2':np.random.randn(5)})In [5]: dfOut[5]: key1 key2 data1 data20 a one -0.549915 -1.5673421 a two -0.037543 -0.8345762 b one -1.267072 1.6288813 b two 0.976757 -1.5496644 a one 2.423714 1.791845/<code>
假設想要按key1進行分組,並計算data1列的平均值。實現方式:訪問data1,並根據key1調用groupby:
<code>In [6]: grouped=df['data1'].groupby(df['key1'])In [7]: groupedOut[7]: <pandas.core.groupby.generic.seriesgroupby>/<code>
變量grouped是一個GroupBy對象。它實際上還沒有進行任何計算,只是含有一些有關分組鍵df[‘key1’]的中間數據而已。換句話說,該對象已經有了接下來對各組執行運算所需的一切信息。例如,可以調用GroupBy的mean方法來計算分組平均值:
<code>In [8]: grouped.mean()Out[8]: key1a 0.612085b -0.145158Name: data1, dtype: float64/<code>
四種分組鍵使用方法,具體如下:
一次傳入多個數組
<code>In [9]: means=df['data1'].groupby([df['key1'],df['key2']]).mean()In [10]: meansOut[10]: key1 key2a one 0.936899 two -0.037543b one -1.267072 two 0.976757Name: data1, dtype: float64/<code>
通過兩個鍵對數據進行了分組,得到的Series具有一個層次化索引(由唯一的鍵對組成):
<code>In [11]: means.unstack()Out[11]: key2 one twokey1 a 0.936899 -0.037543b -1.267072 0.976757/<code>
分組鍵可以是任何長度適當的數組
<code>In [12]: states=np.array(['Ohio','California','California','Ohio','Ohio'])In [13]: years=np.array([2005,2005,2006,2005,2006])In [14]: df['data1'].groupby([states,years]).mean()Out[14]: California 2005 -0.037543 2006 -1.267072Ohio 2005 0.213421 2006 2.423714Name: data1, dtype: float64/<code>
將列名(可以是字符串、數字或其他python對象)用作分組鍵
<code>In [15]: df.groupby('key1').mean()Out[15]: data1 data2key1 a 0.612085 -0.203358b -0.145158 0.039609/<code>
在執行df.groupby('key1').mean()時,結果中沒有key2列。這是因為df[‘key2’]不是數值數據(俗稱“麻煩列”),所以被從結果中排除了。默認情況下,所有數據列都會被整合,雖然有時會被過濾為一個子集。
<code>In [16]: df.groupby(['key1','key2']).mean()Out[16]: data1 data2key1 key2 a one 0.936899 0.112251 two -0.037543 -0.834576b one -1.267072 1.628881 two 0.976757 -1.549664/<code>
GroupBy的size方法
返回一個含有分組大小的Series:
<code>In [17]: df.groupby(['key1','key2']).size()Out[17]: key1 key2a one 2 two 1b one 1 two 1dtype: int64/<code>
閱讀更多 python知識分享 的文章