文章目錄
-
- 便捷的分組平均
- 指定行列及聚合對象
- 分項小計
- 自定義聚合方法
- 複雜的聚合
透視表在一定程度上可以稱作是
split-apply-combine
的快捷方式。
DataFrame
有
pivot_table()
方法,對應的頂級的
pandas.pivot_table()
函數。除了提供便利的
groupby
之外還提供了分項小計
margins
。
- 準備資料集
import numpy as np
import pandas as pd
file = r'../data/tips.csv'
tips = pd.read_csv(file)
tips.head()
total_bill | tip | smoker | day | time | size | |
---|---|---|---|---|---|---|
16.99 | 1.01 | No | Sun | Dinner | 2 | |
1 | 10.34 | 1.66 | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | No | Sun | Dinner | 4 |
tips['tip_pct'] = tips['tip'] / tips['tip'].sum()
tips.head()
total_bill | tip | smoker | day | time | size | tip_pct | |
---|---|---|---|---|---|---|---|
16.99 | 1.01 | No | Sun | Dinner | 2 | 0.001381 | |
1 | 10.34 | 1.66 | No | Sun | Dinner | 3 | 0.002269 |
2 | 21.01 | 3.50 | No | Sun | Dinner | 3 | 0.004784 |
3 | 23.68 | 3.31 | No | Sun | Dinner | 2 | 0.004524 |
4 | 24.59 | 3.61 | No | Sun | Dinner | 4 | 0.004935 |
便捷的分組平均
- 假設根據tips資料集,對time和smoker進行分組平均:
size | tip | tip_pct | total_bill | ||
---|---|---|---|---|---|
time | smoker | ||||
Dinner | No | 2.735849 | 3.126887 | 0.004274 | 20.095660 |
Yes | 2.471429 | 3.066000 | 0.004191 | 21.859429 | |
Lunch | No | 2.511111 | 2.673778 | 0.003655 | 17.050889 |
Yes | 2.217391 | 2.834348 | 0.003874 | 17.399130 |
注意:所有的非數值類型被自動過濾,且預設聚合方法為平均值方法。
指定行列及聚合對象
- 假設我們對tip_pct, size進行聚合,将smoker作用在列上,将time, day作用在行上:
size | tip_pct | ||||
---|---|---|---|---|---|
smoker | No | Yes | No | Yes | |
time | day | ||||
Dinner | Fri | 2.000000 | 2.222222 | 0.003759 | 0.004105 |
Sat | 2.555556 | 2.476190 | 0.004241 | 0.003931 | |
Sun | 2.929825 | 2.578947 | 0.004330 | 0.004807 | |
Thur | 2.000000 | NaN | 0.004101 | NaN | |
Lunch | Fri | 3.000000 | 1.833333 | 0.004101 | 0.003117 |
Thur | 2.500000 | 2.352941 | 0.003645 | 0.004142 |
分項小計
-
在聚合後的基礎上添加margins=True可以實作分項小計:
小計的結果使用All标記,同時列的複合索引根據最進階求和。
size | tip_pct | ||||||
---|---|---|---|---|---|---|---|
smoker | No | Yes | All | No | Yes | All | |
time | day | ||||||
Dinner | Fri | 2.000000 | 2.222222 | 2.166667 | 0.003759 | 0.004105 | 0.004019 |
Sat | 2.555556 | 2.476190 | 2.517241 | 0.004241 | 0.003931 | 0.004091 | |
Sun | 2.929825 | 2.578947 | 2.842105 | 0.004330 | 0.004807 | 0.004449 | |
Thur | 2.000000 | NaN | 2.000000 | 0.004101 | NaN | 0.004101 | |
Lunch | Fri | 3.000000 | 1.833333 | 2.000000 | 0.004101 | 0.003117 | 0.003257 |
Thur | 2.500000 | 2.352941 | 2.459016 | 0.003645 | 0.004142 | 0.003783 | |
All | 2.668874 | 2.408602 | 2.569672 | 0.004090 | 0.004113 | 0.004098 |
自定義聚合方法
- 預設方法是平均值
- 其他聚合方法可通過aggfunc來傳遞
# nan有礙觀瞻就改為0了
tips.pivot_table(values='tip_pct', index=['time', 'smoker'], columns='day', aggfunc=len, margins=True, fill_value=0)
day | Fri | Sat | Sun | Thur | All | |
---|---|---|---|---|---|---|
time | smoker | |||||
Dinner | No | 3 | 45 | 57 | 1 | 106.0 |
Yes | 9 | 42 | 19 | 70.0 | ||
Lunch | No | 1 | 44 | 45.0 | ||
Yes | 6 | 17 | 23.0 | |||
All | 19 | 87 | 76 | 62 | 244.0 |
複雜的聚合
tips.pivot_table(values=['size', 'tip_pct'], index=['time', 'smoker'], columns='day',
aggfunc={'tip_pct': [len, sum], 'size': max}, fill_value=0)
size | tip_pct | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
max | len | sum | |||||||||||
day | Fri | Sat | Sun | Thur | Fri | Sat | Sun | Thur | Fri | Sat | Sun | Thur | |
time | smoker | ||||||||||||
Dinner | No | 2 | 4 | 6 | 2 | 3 | 45 | 57 | 1 | 0.011277 | 0.190861 | 0.246822 | 0.004101 |
Yes | 4 | 5 | 5 | 9 | 42 | 19 | 0.036947 | 0.165081 | 0.091337 | 0.000000 | |||
Lunch | No | 3 | 6 | 1 | 44 | 0.004101 | 0.000000 | 0.000000 | 0.160365 | ||||
Yes | 2 | 4 | 6 | 17 | 0.018699 | 0.000000 | 0.000000 | 0.070409 |
👉pivot_table()參數說明表:
參數名 | 說明 |
---|---|
values | 待聚合的列的名稱,預設所有數值列。 |
index | 用于分組的列名或其他分組鍵,出現在結果透視表的行。 |
columns | 用于分組的列名或其他分組鍵,出現在結果透視表的列。 |
aggfunc | 聚合函數或函數清單,預設為mean。可以是對任何groupby有作用的函數。 |
fill_value | 用于替換結果中的空值的值 |
margins | 添加行列的小計 |