天天看點

Python資料分析 | (31) 透視表和交叉表

目錄

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]
           
Python資料分析 | (31) 透視表和交叉表
tips.pivot_table(index=['day', 'smoker']) #預設每組執行mean聚合運算
           
Python資料分析 | (31) 透視表和交叉表

可以用groupby直接來做。現在,假設我們隻想聚合tip_pct和size,而且想根 據time進行分組。我将smoker放到列上,把day放到行上:

tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
                 columns='smoker')
           
Python資料分析 | (31) 透視表和交叉表

還可以對這個表作進一步的處理,傳入margins=True添加分項小計。這将會 添加标簽為All的行和列,其值對應于單個等級中所有資料的分組統計:

tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
                 columns='smoker', margins=True)
           
Python資料分析 | (31) 透視表和交叉表

這裡,All值為平均數:不單獨考慮煙民與非煙民(All列),不單獨考慮行分 組兩個級别中的任何單項(All行)。

要使用其他的聚合函數,将其傳給aggfunc即可。例如,使用count或len可以 得到有關分組大小的交叉表(計數或頻率):

tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',
                 aggfunc=len, margins=True)
           
Python資料分析 | (31) 透視表和交叉表

如果存在空的組合(也就是NA),你可能會希望設定一個fill_value:

tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],
                 columns='day', aggfunc='mean', fill_value=0)
           
Python資料分析 | (31) 透視表和交叉表

pivot_table的參數說明請參見下表:

Python資料分析 | (31) 透視表和交叉表

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
           
Python資料分析 | (31) 透視表和交叉表

作為調查分析的一部分,我們可能想要根據國籍和用手習慣對這段資料進行 統計彙總。雖然可以用pivot_table實作該功能,但是pandas.crosstab函數會 更友善:

pd.crosstab(data.Nationality, data.Handedness, margins=True)
           
Python資料分析 | (31) 透視表和交叉表

crosstab的前兩個參數可以是數組或Series,或是數組清單。就像小費數 據:

pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
           
Python資料分析 | (31) 透視表和交叉表

3. 總結

最近幾篇部落格我們介紹了pandas資料分組工具,它既有助于資料清理,也有助于模組化或統計分析工作。之後,我們會學習幾個例子,對真實資料使用groupby。後續的幾篇部落格我們會關注時間序列資料。

繼續閱讀