目錄
1. 透視表
2. 交叉表:crosstab
3. 總結
1. 透視表
透視表(pivot table)是各種電子表格程式和其他資料分析軟體中一種常見的 資料彙總工具。它根據一個或多個鍵對資料進行聚合,并根據行和列上的分 組鍵将資料配置設定到各個矩形區域中。在Python和pandas中,可以通過本部落格所 介紹的groupby功能以及(能夠利用階層化索引的)重塑運算制作透視表。
DataFrame有一個pivot_table方法,此外還有一個頂級的pandas.pivot_table 函數。除能為groupby提供便利之外,pivot_table還可以添加分項小計,也叫 做margins。
回到小費資料集,假設我想要根據day和smoker計算分組平均數 (pivot_table的預設聚合類型),并将day和smoker放到行上:
tips = pd.read_csv('examples/tips.csv')
# Add tip percentage of total bill
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips[:6]

tips.pivot_table(index=['day', 'smoker']) #預設每組執行mean聚合運算
可以用groupby直接來做。現在,假設我們隻想聚合tip_pct和size,而且想根 據time進行分組。我将smoker放到列上,把day放到行上:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker')
還可以對這個表作進一步的處理,傳入margins=True添加分項小計。這将會 添加标簽為All的行和列,其值對應于單個等級中所有資料的分組統計:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker', margins=True)
這裡,All值為平均數:不單獨考慮煙民與非煙民(All列),不單獨考慮行分 組兩個級别中的任何單項(All行)。
要使用其他的聚合函數,将其傳給aggfunc即可。例如,使用count或len可以 得到有關分組大小的交叉表(計數或頻率):
tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',
aggfunc=len, margins=True)
如果存在空的組合(也就是NA),你可能會希望設定一個fill_value:
tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],
columns='day', aggfunc='mean', fill_value=0)
pivot_table的參數說明請參見下表:
2. 交叉表:crosstab
交叉表(cross-tabulation,簡稱crosstab)是一種用于計算分組頻率的特殊透視表。看下面的例子:
from io import StringIO
data = """\
Sample Nationality Handedness
1 USA Right-handed
2 Japan Left-handed
3 USA Right-handed
4 Japan Right-handed
5 Japan Left-handed
6 Japan Right-handed
7 USA Right-handed
8 USA Left-handed
9 Japan Right-handed
10 USA Right-handed"""
data = pd.read_table(StringIO(data), sep='\s+')
data
作為調查分析的一部分,我們可能想要根據國籍和用手習慣對這段資料進行 統計彙總。雖然可以用pivot_table實作該功能,但是pandas.crosstab函數會 更友善:
pd.crosstab(data.Nationality, data.Handedness, margins=True)
crosstab的前兩個參數可以是數組或Series,或是數組清單。就像小費數 據:
pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
3. 總結
最近幾篇部落格我們介紹了pandas資料分組工具,它既有助于資料清理,也有助于模組化或統計分析工作。之後,我們會學習幾個例子,對真實資料使用groupby。後續的幾篇部落格我們會關注時間序列資料。