給妹子講python-S02E21數據透視表
來自專欄 給妹子講python
python,不管你懂沒懂,反正妹子是搞懂了
轉載請註明:知乎專欄《給妹子講python》
【要點搶先看】
1.透視表的基本使用2.透視表實現高維度的行列分組3.透視表實現多屬性觀察及自定義統計函數
【妹子說】這一季里,各種表啊什麼的可真多啊,這又是什麼鬼~
恩,我懂你的套路了,我先不說透視表是啥,我還是先說一個問題,我們這一集舉泰坦尼克號的乘客信息這個經典數據。
import numpy as npimport pandas as pdimport seaborn as snstitanic = sns.load_dataset(titanic)print(titanic.head()) survived pclass sex age sibsp parch fare embarked class 0 0 3 male 22.0 1 0 7.2500 S Third1 1 1 female 38.0 1 0 71.2833 C First2 1 3 female 26.0 0 0 7.9250 S Third3 1 1 female 35.0 1 0 53.1000 S First4 0 3 male 35.0 0 0 8.0500 S Third who adult_male deck embark_town alive alone0 man True NaN Southampton no False1 woman False C Cherbourg yes False2 woman False NaN Southampton yes True3 woman False C Southampton yes False4 man True NaN Southampton no True
首先,我們按性別分組,看看男性和女性的生還率各是多少?
【妹子說】這用上一集講的groupby不就完了?看看,輕鬆解決~
print(titanic.groupby(sex)[survived].mean())sexfemale 0.742038male 0.188908Name: survived, dtype: float64
恩,看來掌握的不錯,那接著再來,如果加上另一個維度,我們看看不同性別和船艙等級的生還情況:
print(titanic.groupby([sex,class])[survived].mean())sex class female First 0.968085 Second 0.921053 Third 0.500000male First 0.368852 Second 0.157407 Third 0.135447Name: survived, dtype: float64
我們把他轉換成DataFrame:
print(titanic.groupby([sex,class])[survived].mean().unstack())class First Second Thirdsex female 0.968085 0.921053 0.500000male 0.368852 0.157407 0.135447
【妹子說】這說來說去不還是上一集的東西嗎?
別急,上一集的內容確實能解決這裡的問題,但是由於類似的多維GroupBy應用場景非常普遍,因此Pandas提供了一個快捷方式pivot_table來快速解決多維的累計分析任務。
在函數中指定觀察的數據內容是survived,索引採用sex列,而列則使用class,sex和class就是我們的分組維度,而survived就是我們考察的每組的變數值。
print(titanic.pivot_table(survived, index=sex, columns=class))class First Second Thirdsexfemale 0.968085 0.921053 0.500000male 0.368852 0.157407 0.135447
這種透視表的代碼與GroupBy相比,實現的效果一樣,某種程度上更能表徵出結果的形態。
【妹子說】額,但是我感覺好像也還是差不了多少啊
可能這個例子舉得比較簡單,實際上,透視表在表達更複雜的分組時,優勢就明顯了。
比如我們在分組中加入第三個維度:年齡,且對年齡進行劃分,即進一步的分為0~18歲和18對~80歲兩個範圍。
age = pd.cut(titanic[age],[0, 18, 80])print(titanic.pivot_table(survived,[sex,age],class))class First Second Thirdsex age female (0, 18] 0.909091 1.000000 0.511628 (18, 80] 0.972973 0.900000 0.423729male (0, 18] 0.800000 0.600000 0.215686 (18, 80] 0.375000 0.071429 0.133663
從結果中我們不難看出,最終的結果DataFrame里,sex和age作為複合索引,class仍作為column列名,可以這麼說,在pivot_table函數里,可以按照位置進行參數對應,第一個參數就是分組後關注的屬性值,第二個和第三個參數都是用來進行分組的屬性,其中第二個作為結果的複合索引,而第三個參數作為結果的列名呈現。
【妹子說】那這麼說,在分組時,自然也能對列再增加一個分組維度啦?
沒錯,那我們再增加票價這麼一個分組維度,並在結果的列中進行呈現,這裡多說一句,我們對票價的分組分割點就是最低價和最高價的平均值:
age = pd.cut(titanic[age],[0, 18, 80])fare = pd.qcut(titanic[fare],2)print(titanic.pivot_table(survived, [sex,age],[fare,class]))fare [0, 14.454] (14.454, 512.329] class First Second Third First Second sex age female (0, 18] NaN 1.000000 0.714286 0.909091 1.000000 (18, 80] NaN 0.880000 0.444444 0.972973 0.914286 male (0, 18] NaN 0.000000 0.260870 0.800000 0.818182 (18, 80] 0.0 0.098039 0.125000 0.391304 0.030303 fare class Third sex age female (0, 18] 0.318182 (18, 80] 0.391304 male (0, 18] 0.178571 (18, 80] 0.192308
最終分組的結果為四維的累計數據表,行和列均為二重形式。
最後,我們再對透視表做一個拓展,首先我們要明確:
1.分組的統計值默認是平均數,但是可以顯式的指定為其他統計函數:sum、mean、count、min、max等
2.最終通過分組來觀測的值可以是多個
3.每個觀測值也可以對應使用不同的統計函數
【妹子說】來來來,搞個例子,把這三個點都包含進去
沒問題,那我們以性別和船艙等級為分組依據,觀測各個分組裡票價fare的均值和生還人數survived的總數:
print(titanic.pivot_table(index=sex, columns=class,aggfunc={survived:sum, fare:mean})) fare survived class First Second Third First Second Thirdsex female 106.125798 21.970121 16.118810 91 70 72male 67.226127 19.741782 12.661633 45 17 47
【妹子說】恩,這個用起來真的很方便,那還有一個情況,我們通過分組,可以看到每個性別和每個船艙等級對應的生還率,那如果我想同時看看每個性別對應的所有船艙的生還率,以及每個船艙等級里所有人的生還率呢?
恩,問得好呀,這裡有一個margin參數可以實現你想要的效果:
print(titanic.pivot_table(survived,index=sex,columns=class,margins=True))class First Second Third Allsex female 0.968085 0.921053 0.500000 0.742038male 0.368852 0.157407 0.135447 0.188908All 0.629630 0.472826 0.242363 0.383838
對各行、各列都有匯總的均值統計,是不是一目了然?
【妹子說】透視表還是很強大的呀,尤其是進行二維以上的高維分組的情況下,同時在進行附加屬性的觀察以及分組劃分上也是十分方便的!
推薦閱讀:
※Excel 函數「vlookup」可不可以 lookup 到近似值?函數該怎麼寫?
※如果想自學excel軟體難不難?
※如何解釋office那麼貴還是那麼多人用?
※在excel中,如何實現讓下一行永遠等於上一行加一,在刪除當中某一行之後保證之後都不出現亂碼?
※Excel 怎麼設定在整個文件中查找,而不是在一個 sheet 中查找?
TAG:數據分析 | 數據透視表 | MicrosoftExcel |