Python 小案例(二)长宽表转换
在日常与运营、产品打交道时,你会发现他们提供给数分的 Excel 大多数是宽表,而数分提供给业务的多是长表。因此进行长宽表转换就显得很有必要性了。
代码语言:javascript复制import pandas as pd
长表转宽表
代码语言:javascript复制# 构造长表数据
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 方式
代码语言:javascript复制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 方式
代码语言:javascript复制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 |
宽表转长表
代码语言:javascript复制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 |
共勉~