import numpy as np
import pandas as pd
df = pd.read_csv('C:/Users/admin/Desktop/joyful-pandas-master/joyful-pandas-master/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
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 |
---|
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 |
---|
pd.pivot_table(df,index='ID',columns='Gender',values='Height',aggfunc=['mean','sum']).head()
| mean | sum |
---|
Gender | F | M | F | M |
---|
ID | | | | |
---|
1101 | NaN | 173.0 | NaN | 173.0 |
---|
1102 | 192.0 | NaN | 192.0 | NaN |
---|
1103 | NaN | 186.0 | NaN | 186.0 |
---|
1104 | 167.0 | NaN | 167.0 | NaN |
---|
1105 | 159.0 | NaN | 159.0 | NaN |
---|
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum'],margins = True).head()
| 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 | ... | Weight |
---|
| Gender | F | M | ... | F | M |
---|
| Address | street_1 | street_2 | street_4 | street_5 | street_6 | street_7 | street_1 | street_2 | street_4 | street_5 | ... | street_4 | street_5 | street_6 | street_7 | street_1 | street_2 | street_4 | street_5 | street_6 | street_7 |
---|
School | Class | | | | | | | | | | | | | | | | | | | | | |
---|
S_1 | C_1 | NaN | 179.5 | 159.0 | NaN | NaN | NaN | 173.0 | 186.0 | NaN | NaN | ... | 64.0 | NaN | NaN | NaN | 63.0 | 82.0 | NaN | NaN | NaN | NaN |
---|
C_2 | NaN | NaN | 176.0 | 162.0 | 167.0 | NaN | NaN | NaN | NaN | 188.0 | ... | 94.0 | 63.0 | 63.0 | NaN | NaN | NaN | NaN | 68.0 | 53.0 | NaN |
---|
C_3 | 175.0 | NaN | NaN | 187.0 | NaN | NaN | NaN | 195.0 | 161.0 | NaN | ... | NaN | 69.0 | NaN | NaN | NaN | 70.0 | 68.0 | NaN | NaN | 82.0 |
---|
S_2 | C_1 | NaN | NaN | NaN | 159.0 | 161.0 | NaN | NaN | NaN | 163.5 | NaN | ... | NaN | 97.0 | 61.0 | NaN | NaN | NaN | 71.0 | NaN | NaN | 84.0 |
---|
C_2 | NaN | NaN | NaN | NaN | NaN | 188.5 | 175.0 | NaN | 155.0 | 193.0 | ... | NaN | NaN | NaN | 76.5 | 74.0 | NaN | 91.0 | 100.0 | NaN | NaN |
---|
C_3 | NaN | NaN | 157.0 | NaN | 164.0 | 190.0 | NaN | NaN | 187.0 | 171.0 | ... | 78.0 | NaN | 81.0 | 99.0 | NaN | NaN | 73.0 | 88.0 | NaN | NaN |
---|
C_4 | NaN | 176.0 | NaN | NaN | 175.5 | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | 57.0 | NaN | NaN | NaN | NaN | NaN | NaN | 82.0 |
---|
7 rows × 24 columns
1.3、crosstab 交叉表
pd.crosstab(index = df['Address'],columns=df['Gender'])
Gender | F | M |
---|
Address | | |
---|
street_1 | 1 | 2 |
---|
street_2 | 4 | 2 |
---|
street_4 | 3 | 5 |
---|
street_5 | 3 | 3 |
---|
street_6 | 5 | 1 |
---|
street_7 | 3 | 3 |
---|
pd.crosstab(index=df['Address'],columns=df['Gender'],values=np.random.randint(1,20,df.shape[0]),aggfunc='min')
Gender | F | M |
---|
Address | | |
---|
street_1 | 8 | 5 |
---|
street_2 | 10 | 11 |
---|
street_4 | 17 | 1 |
---|
street_5 | 3 | 5 |
---|
street_6 | 9 | 9 |
---|
street_7 | 7 | 2 |
---|
pd.crosstab(index = df['Address'],columns = df['Gender'],normalize='all',margins=True)
Gender | F | M | All |
---|
Address | | | |
---|
street_1 | 0.028571 | 0.057143 | 0.085714 |
---|
street_2 | 0.114286 | 0.057143 | 0.171429 |
---|
street_4 | 0.085714 | 0.142857 | 0.228571 |
---|
street_5 | 0.085714 | 0.085714 | 0.171429 |
---|
street_6 | 0.142857 | 0.028571 | 0.171429 |
---|
street_7 | 0.085714 | 0.085714 | 0.171429 |
---|
All | 0.542857 | 0.457143 | 1.000000 |
---|
2、其他变形方法
2.1、melt方法
df_m = df[['ID','Gender','Math']]
df_m.head()
| ID | Gender | Math |
---|
0 | 1101 | M | 34.0 |
---|
1 | 1102 | F | 32.5 |
---|
2 | 1103 | M | 87.2 |
---|
3 | 1104 | F | 80.4 |
---|
4 | 1105 | F | 84.8 |
---|
pivoted = df.pivot(index='ID',columns='Gender',values='Math')
result = pivoted.reset_index().melt(id_vars=['ID'],value_vars=['F','M'],value_name='Math')\
.dropna().set_index('ID').sort_index()
result.head()
| Gender | Math |
---|
ID | | |
---|
1101 | M | 34.0 |
---|
1102 | F | 32.5 |
---|
1103 | M | 87.2 |
---|
1104 | F | 80.4 |
---|
1105 | F | 84.8 |
---|
2.2、压缩与展开
- stack()即“堆叠”,作用是将列旋转到行;
- unstack()即stack()的反操作,将行旋转到列;
- stack和unstack默认操作为最内层
- stack和unstack默认旋转轴的级别将会操作最低级别(最内层)
df_s = pd.pivot_table(df,index=['Class','ID'],columns='Gender',values=['Height','Weight'])
df_s.groupby('Class').head(2)
| | Height | Weight |
---|
| Gender | F | M | F | M |
---|
Class | ID | | | | |
---|
C_1 | 1101 | NaN | 173.0 | NaN | 63.0 |
---|
1102 | 192.0 | NaN | 73.0 | NaN |
---|
C_2 | 1201 | NaN | 188.0 | NaN | 68.0 |
---|
1202 | 176.0 | NaN | 94.0 | NaN |
---|
C_3 | 1301 | NaN | 161.0 | NaN | 68.0 |
---|
1302 | 175.0 | NaN | 57.0 | NaN |
---|
C_4 | 2401 | 192.0 | NaN | 62.0 | NaN |
---|
2402 | NaN | 166.0 | NaN | 82.0 |
---|
- 由于stack和unstack默认是操作最里层的数据,当我们想操作外层的数据时,就要传入一个层级序号或名称来拆分一个不同的层级。
df_stacked = df_s.stack()
df_stacked.groupby('Class').head(2)
| | | Height | Weight |
---|
Class | ID | Gender | | |
---|
C_1 | 1101 | M | 173.0 | 63.0 |
---|
1102 | F | 192.0 | 73.0 |
---|
C_2 | 1201 | M | 188.0 | 68.0 |
---|
1202 | F | 176.0 | 94.0 |
---|
C_3 | 1301 | M | 161.0 | 68.0 |
---|
1302 | F | 175.0 | 57.0 |
---|
C_4 | 2401 | F | 192.0 | 62.0 |
---|
2402 | M | 166.0 | 82.0 |
---|
df_stacked.head()
| | | Height | Weight |
---|
Class | ID | Gender | | |
---|
C_1 | 1101 | M | 173.0 | 63.0 |
---|
1102 | F | 192.0 | 73.0 |
---|
1103 | M | 186.0 | 82.0 |
---|
1104 | F | 167.0 | 81.0 |
---|
1105 | F | 159.0 | 64.0 |
---|
df_unstacked = df_stacked.unstack()
df_unstacked.groupby('Class').head(2)
| | Height | Weight |
---|
| Gender | F | M | F | M |
---|
Class | ID | | | | |
---|
C_1 | 1101 | NaN | 173.0 | NaN | 63.0 |
---|
1102 | 192.0 | NaN | 73.0 | NaN |
---|
C_2 | 1201 | NaN | 188.0 | NaN | 68.0 |
---|
1202 | 176.0 | NaN | 94.0 | NaN |
---|
C_3 | 1301 | NaN | 161.0 | NaN | 68.0 |
---|
1302 | 175.0 | NaN | 57.0 | NaN |
---|
C_4 | 2401 | 192.0 | NaN | 62.0 | NaN |
---|
2402 | NaN | 166.0 | NaN | 82.0 |
---|
3、哑变量与因子化
3.1、Dummy Variable(哑变量)
df_d = df[['Class','Gender','Weight']]
df_d.head()
| Class | Gender | Weight |
---|
0 | C_1 | M | 63 |
---|
1 | C_1 | F | 73 |
---|
2 | C_1 | M | 82 |
---|
3 | C_1 | F | 81 |
---|
4 | C_1 | F | 64 |
---|
pd.get_dummies(df_d[['Class','Gender']]).join(df_d['Weight']).head()
| Class_C_1 | Class_C_2 | Class_C_3 | Class_C_4 | Gender_F | Gender_M | Weight |
---|
0 | 1 | 0 | 0 | 0 | 0 | 1 | 63 |
---|
1 | 1 | 0 | 0 | 0 | 1 | 0 | 73 |
---|
2 | 1 | 0 | 0 | 0 | 0 | 1 | 82 |
---|
3 | 1 | 0 | 0 | 0 | 1 | 0 | 81 |
---|
4 | 1 | 0 | 0 | 0 | 1 | 0 | 64 |
---|
3.2、factorize方法
codes,uniques = pd.factorize(['a',None,'c','b','a'],sort=True)
display(codes)
display(uniques)
array([ 0, -1, 2, 1, 0], dtype=int64)
array(['a', 'b', 'c'], dtype=object)