Python小案例(二)长宽表转换
在日常与运营、产品打交道时,你会发现他们提供给数分的Excel大多数是宽表,而数分提供给业务的多是长表。因此进行长宽表转换就显得很有必要性了。
import pandas as pd
长表转宽表
df_len = pd.DataFrame(
{'阶段':['小学','小学','小学','小学','小学','小学','小学','小学','小学','初中','初中','初中','初中','初中','初中'],
'科目':['英语','英语','英语','语文','语文','语文','数学','数学','数学','数学','数学','数学','语文','语文','语文'],
'基础':[10,10,10,2,2,2,8,8,8,5,5,5,6,6,6],
'等级':['一级','二级','三级','一级','二级','三级','一级','二级','三级','一级','二级','三级','一级','二级','三级'],
'加成':[3.2,1.7,3.1,3.6,2.8,4,2.2,2.1,1.7,1.2,2,2.4,2.7,1.3,1.9]})
df_len.head()
| 阶段 | 科目 | 基础 | 等级 | 加成 |
---|
0 | 小学 | 英语 | 10 | 一级 | 3.2 |
---|
1 | 小学 | 英语 | 10 | 二级 | 1.7 |
---|
2 | 小学 | 英语 | 10 | 三级 | 3.1 |
---|
3 | 小学 | 语文 | 2 | 一级 | 3.6 |
---|
4 | 小学 | 语文 | 2 | 二级 | 2.8 |
---|
groupby方式
result = df_len.groupby(['阶段', '科目', '基础', '等级'])['加成'].max().unstack(3).dropna(axis=0,
how='any').reset_index().rename_axis([None], axis=1)
order = ['阶段', '科目', '基础', '一级', '二级', '三级']
result[order].to_excel('wide_table.xlsx', index=None)
result[order]
| 阶段 | 科目 | 基础 | 一级 | 二级 | 三级 |
---|
0 | 初中 | 数学 | 5 | 1.2 | 2.0 | 2.4 |
---|
1 | 初中 | 语文 | 6 | 2.7 | 1.3 | 1.9 |
---|
2 | 小学 | 数学 | 8 | 2.2 | 2.1 | 1.7 |
---|
3 | 小学 | 英语 | 10 | 3.2 | 1.7 | 3.1 |
---|
4 | 小学 | 语文 | 2 | 3.6 | 2.8 | 4.0 |
---|
pivot_table方式
result = df_len.pivot_table(index=['阶段', '科目', '基础'],
columns=['等级'],
values=['加成']).reset_index()
result = result.set_index(['阶段', '科目', '基础'])
result.columns = result.columns.droplevel(0)
result = result.reset_index().rename_axis([None], axis=1)
order = ['阶段', '科目', '基础', '一级', '二级', '三级']
result[order].to_excel('wide_table.xlsx', index=None)
result[order]
| 阶段 | 科目 | 基础 | 一级 | 二级 | 三级 |
---|
0 | 初中 | 数学 | 5 | 1.2 | 2.0 | 2.4 |
---|
1 | 初中 | 语文 | 6 | 2.7 | 1.3 | 1.9 |
---|
2 | 小学 | 数学 | 8 | 2.2 | 2.1 | 1.7 |
---|
3 | 小学 | 英语 | 10 | 3.2 | 1.7 | 3.1 |
---|
4 | 小学 | 语文 | 2 | 3.6 | 2.8 | 4.0 |
---|
宽表转长表
df_wide = pd.read_excel('wide_table.xlsx', index_col=[0,1,2])
df_wide.head()
| | | 一级 | 二级 | 三级 |
---|
阶段 | 科目 | 基础 | | | |
---|
初中 | 数学 | 5 | 1.2 | 2.0 | 2.4 |
---|
语文 | 6 | 2.7 | 1.3 | 1.9 |
---|
小学 | 数学 | 8 | 2.2 | 2.1 | 1.7 |
---|
英语 | 10 | 3.2 | 1.7 | 3.1 |
---|
语文 | 2 | 3.6 | 2.8 | 4.0 |
---|
result = pd.DataFrame(df_wide.stack()).reset_index()
result.columns = ['阶段', '科目', '基础', '等级', '加成']
result.head()
| 阶段 | 科目 | 基础 | 等级 | 加成 |
---|
0 | 初中 | 数学 | 5 | 一级 | 1.2 |
---|
1 | 初中 | 数学 | 5 | 二级 | 2.0 |
---|
2 | 初中 | 数学 | 5 | 三级 | 2.4 |
---|
3 | 初中 | 语文 | 6 | 一级 | 2.7 |
---|
4 | 初中 | 语文 | 6 | 二级 | 1.3 |
---|
共勉~