“拆分-應用-合併"分組運算過程,python分組技術groupby應用詳解


“拆分-應用-合併

前言

“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>


分享到:


相關文章: