數據分組
數據分組就是根據一個或多個鍵(可以是函數、數組或df列名)將數據分成若干組,然后對分組后的數據分別進行匯總計算,並將匯總計算后的結果進行合並,被用作匯總計算的函數成為聚合函數。
數據分組的具體分組流程如下圖所示。
Excel 中有數據分組這個功能,但是在使用這個功能以前要先對鍵進行排序(你要按照哪一列進行分組,那么鍵就是這一列),升序或降序都可以,排序前后的結果如下圖所示。
鍵值排序完成后,選中待分組區域,然后依次單擊菜單欄中的數據>分類匯總即可。分類字段、匯總方式都可以根據需求選擇。匯總方式就是對分組后的數據進行什么樣的運算,我們這里進行的是計數運算, 因此在選定匯總項中勾選數值復選框。分類匯總對話框及分組結果如下圖所示。
Excel中常見的匯總方式如下表所示。
在Python中對數據分組利用的是groupby()方法,這個有點類似於sql中的groupby,在接下來的幾個小節里面,我們會重點介紹Python中的groupby()方法。
分組鍵是列名
分組鍵是列名時直接將某一列或多列的列名傳給groupby(),groupby()方法就會按照這一列或多列進行分組。
按照一列進行分組
從上面的結果可以看出,如果只傳入列名,運行groupby()方法以后返回的不是一個DataFrame對象,而是一個DataFrameGroupBy對象,這個對象里面包含着分組以后的若干組數據,但是沒有直接顯示出來,需要對這些分組進行匯總計算以后才能顯示出來。
上面的代碼是根據客戶分類對所有數據進行分組,然后對分組以后的數據分別進行計數運算,最后進行合並。
由於對分組后的數據進行了計數運算,因此每一列都會有一個結果,但是如果對分組后的結果做一些數值運算,這個時候就只有數據類型是數值(int、float)的列才會參與運算,比如下面的求和運算。
我們把這種對分組后的數據進行匯總運算的操作稱為聚合,使用的函數稱為聚合函數。
前面講過的匯總函數都可以作為聚合函數對分組后的數據進行聚合。
按照多列進行分組
上面分組鍵是某一列,即按照一列進行分組,也可以按照多列進行分組,只要將多個列名以列表的形式傳給groupby()即可,匯總計算方式與按照單列進行分組以后數據運算的方式一致。
無論分組鍵是一列還是多列,只要直接在分組后的數據上進行匯總計算,就是對所有可以計算的列進行計算。有時候我們不需要對所有的列進行計算,這時候就可以把想要計算的列(可以是單列,也可以是多列)通過索引的方式取出來,然后在取出來這列數據的基礎上進行匯總計算。
比如我們想看一下A、B、C類客戶分別有多少,我們先按照客戶分類進行分組,然后把用戶ID這一列取出來,在這一列的基礎上進行計數匯總計算即可。
分組鍵是Series
把DataFrame的其中一列取出來就是一個Series,比如下面的df["客戶分類"]就是一個Series。
分組鍵是列名與分組鍵是Series的唯一區別就是,給groupby()方法傳入了什么,其他都一樣。可以按照一個或多個Series進行分組,分組以后的匯總計算也是完全一樣的,也支持對分組以后的某些列進行匯總計算。
按照一個Series進行分組
按照多個Series進行分組
神奇的aggregate方法
前面用到的聚合函數都是直接在DataFrameGroupBy上調用的,這樣分組以后所有列做的都是同一種匯總運算,且一次只能使用一種匯總方式。
aggregate的第一個神奇之處在於,一次可以使用多種匯總方式,比如下面的例子先對分組后的所有列進行計數匯總運算,然后對所有列做求和匯總運算。
aggregate的第二個神奇之處在於,可以針對不同的列做不同的匯總運算,比如下面的例子,我們想看不同類別的用戶有多少,那么對用戶ID 進行計數;我們想看不同類別的用戶在7、8月的銷量,則需要對銷量進行求和。
對分組后的結果重置索引
通過上節代碼運行的結果可以看出,DataFrameGroupBy 對象經過匯總運算以后的形式並不是標准的DataFrame形式。為了接下來對分組結果進行進一步處理與分析,我們需要把非標准形式轉化為標准的DataFrame 形式,利用的方法就是重置索引reset_index()方法,具體實現如下所示。
數據透視表
數據透視表實現的功能與數據分組類似但又不同,數據分組是在一維(行)方向上不斷拆分,而數據透視表是在行、列方向上同時拆分。
下圖為數據分組與數據透視表的對比。
數據透視表不管是在Excel還是Python中都是一個很重要的功能,大家需要熟練掌握。
Excel 中的數據透視表在插入菜單欄中,單擊插入數據透視表以后就會看到如下圖所示的界面。下圖左側為數據透視表中的所有字段,右側為數據透視表的選項,把左側字段拖入右側對應的框中即完成了數據透視表的制作。
下圖展示了讓客戶分類作為行標簽,區域作為列標簽,用戶 ID 作為值,且值字段的計算類型為計數的結果。
在數據透視表中把多個字段拖到行對應的框中作為行標簽,同樣把多個字段拖到列對應的框中作為列標簽,把多個字段拖到值對應的框中作為值,而且可以對不同的值字段選擇不同的計算類型,請大家自行練習。
Python中數據透視表的制作原理與Excel中的制作原理是一樣的。
Python中的數據透視表用到的是pivot_table()方法。
接下來看一些具體實例:客戶分類作為index,區域作為columns,用戶ID作為values,對values執行count運算,運行結果如下:
上面的運行結果與Excel的不同之處就是沒有合計列,Python數據透視表中的合計列默認是關閉的,讓其等於True就可以顯示出來,示例如下所示。
合計列的名稱默認為All,可以通過設置參數margins_name的值進行修改,示例如下所示。
NaN 表示缺失值,我們可以通過設置參數 fill_value 的值對缺失值進行填充,示例如下所示。
aggfunc 用來表示計算類型,當只傳入一種類型時,表示對所有的值字段都進行同樣的計算;如果需要對不同的值進行不同的計算類型,則需要傳入一個字典,其中鍵為列名,值為計算方式。下面對用戶ID進行計數,對7月銷量進行求和。
為了便於分析與處理,我們一般會對數據透視表的結果重置索引,利用的方法同樣是reset_index()。
小結
數據分組
分組鍵是列名
df.groupby(["客戶分類","區域"]).count()
df.groupby("客戶分類")[["7月銷量","8月銷量","9月銷量"]].mean()
aggregate()
df.groupby("客戶分類").aggregate(["count","sum"])
df.groupby("客戶分類").aggregate({"用戶ID":"count","7月銷量":"sum","8月銷量":sum}) # 很棒!
數據分組完成后,重置索引 reset_index
df.groupby(["客戶分類","區域"]).count().reset_index()
數據透視表
pd.pivot_table()
pd.pivot_table(df,index=["客戶分類"],columns=["區域"],values=["用戶ID","7月銷量"],aggfunc={"用戶ID":"count","7月銷量":"sum"},margins=True,fill_value=0)