目录
导入数据
import numpy as np
import pandas as pd
df = pd.read_csv('data/table.csv')
df.head()
School | Class | ID | Gender | Address | Height | Weight | Math | Physics | |
---|---|---|---|---|---|---|---|---|---|
0 | S_1 | C_1 | 1101 | M | street_1 | 173 | 63 | 34.0 | A+ |
1 | S_1 | C_1 | 1102 | F | street_2 | 192 | 73 | 32.5 | B+ |
2 | S_1 | C_1 | 1103 | M | street_2 | 186 | 82 | 87.2 | B+ |
3 | S_1 | C_1 | 1104 | F | street_2 | 167 | 81 | 80.4 | B- |
4 | S_1 | C_1 | 1105 | F | street_4 | 159 | 64 | 84.8 | B+ |
1. 透视表
1. 1 pivot
一般状态下,数据在DataFrame会以压缩(stacked)状态存放,例如上面的Gender,两个类别被叠在一列中,pivot函数可将某一列作为新的cols:
df.pivot(index='ID',columns='Gender',values='Height').head()
Gender | F | M |
---|---|---|
ID | ||
1101 | NaN | 173.0 |
1102 | 192.0 | NaN |
1103 | NaN | 186.0 |
1104 | 167.0 | NaN |
1105 | 159.0 | NaN |
然而pivot函数具有很强的局限性,除了功能上较少之外,还不允许values中出现重复的行列索引对(pair),例如下面的语句就会报错:
#df.pivot(index='School',columns='Gender',values='Height').head()
所以我们在这里使用pivot_table
1.2. pivot_table
首先,再现上面的操作:
pd.pivot_table(df,index='ID',columns='Gender',values='Height').head()
Gender | F | M |
---|---|---|
ID | ||
1101 | NaN | 173.0 |
1102 | 192.0 | NaN |
1103 | NaN | 186.0 |
1104 | 167.0 | NaN |
1105 | 159.0 | NaN |
由于功能相对更多,速度上是比不上原来的pivot函数的:
%timeit df.pivot(index='ID',columns='Gender',values='Height')
%timeit pd.pivot_table(df,index='ID',columns='Gender',values='Height')
3.74 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
16.9 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
Pandas中提供了各种选项,下面介绍常用参数:
- aggfunc:对组内进行聚合统计,可传入各类函数,默认为’mean’
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum']).head()
mean | sum | |||
---|---|---|---|---|
Gender | F | M | F | M |
School | ||||
S_1 | 173.125000 | 178.714286 | 1385 | 1251 |
S_2 | 173.727273 | 172.000000 | 1911 | 1548 |
- margins:汇总边际状态
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum'],margins=True).head()
#margins_name可以设置名字,默认为'All'
mean | sum | |||||
---|---|---|---|---|---|---|
Gender | F | M | All | F | M | All |
School | ||||||
S_1 | 173.125000 | 178.714286 | 175.733333 | 1385 | 1251 | 2636 |
S_2 | 173.727273 | 172.000000 | 172.950000 | 1911 | 1548 | 3459 |
All | 173.473684 | 174.937500 | 174.142857 | 3296 | 2799 | 6095 |
- 行、列、值都可以为多级
pd.pivot_table(df,index=['School','Class'],
columns=['Gender','Address'],
values=['Height','Weight'])
Height | Height | Height | Height | Height | Height | Height | Height | Height | Height | Height | Height | Weight | Weight | Weight | Weight | Weight | Weight | Weight | Weight | Weight | Weight | Weight | Weight | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Gender | F | F | F | F | F | F | M | M | M | M | M | M | F | F | F | F | F | F | M | M | M | M | M | M | |
Address | street_1 | street_2 | street_4 | street_5 | street_6 | street_7 | street_1 | street_2 | street_4 | street_5 | street_6 | street_7 | street_1 | street_2 | street_4 | street_5 | street_6 | street_7 | street_1 | street_2 | street_4 | street_5 |