
本文介绍一种高效、可复用的 pandas 数据重塑方法:将原始宽表中多个“element”列(如 element #1–#3)转换为行索引(fin_element),同时将 financial_period(如 prior_year、current_year)升维为列头,实现从宽表到规范长-宽混合结构的精准转换。
本文介绍一种高效、可复用的 pandas 数据重塑方法:将原始宽表中多个“element”列(如 element #1–#3)转换为行索引(fin_element),同时将 financial_period(如 prior_year、current_year)升维为列头,实现从宽表到规范长-宽混合结构的精准转换。
在处理财务或指标类结构化数据时,常需将多组同质指标(如 element #1, element #2, element #3)从列展开为行,并将时间/周期维度(如 financial_period)转为列头——这既非标准 pivot(因存在重复索引组合),也非单纯 melt 可解。正确路径是组合使用 set_index + unstack + stack,通过多级索引的升降维完成“双轴旋转”。
以下为完整解决方案(基于您提供的示例数据):
import pandas as pd
# 示例数据
df = pd.DataFrame({
'University id #': [1, 1],
'Year': [2022, 2022],
'financial_period': ['prior_year', 'current_year'],
'element #1': ['$1', '$2'],
'element #2': ['$3', '$5'],
'element #3': ['$2', '$0']
})
result = (
df
.set_index(['University id #', 'Year', 'financial_period']) # 设定三重索引
.rename_axis('fin_element', axis=1) # 将列名轴重命名为 fin_element
.unstack('financial_period') # 将 financial_period 升为列头(生成 MultiIndex 列)
.stack('fin_element') # 将 fin_element 降为行索引(恢复普通列)
.sort_index(axis=1, ascending=False) # 按列名排序:prior_year 在前,current_year 在后
.rename_axis(None, axis=1) # 清除列索引名称
.reset_index() # 将索引还原为普通列
)
print(result)
输出结果:
University id # Year fin_element prior_year current_year 0 1 2022 element #1 $1 $2 1 1 2022 element #2 $3 $5 2 1 2022 element #3 $2 $0
✅ 关键原理说明:
- set_index(...) 构建唯一标识组合(University id #, Year, financial_period),为后续透视奠定基础;
- rename_axis('fin_element', axis=1) 是语义化关键一步——它将原列名(element #1 等)逻辑映射为新维度 fin_element,便于后续 stack 识别;
- unstack('financial_period') 将该索引层转为列,生成 (fin_element, financial_period) 的 MultiIndex 列结构;
- stack('fin_element') 则将 fin_element 从列层级“折叠”回行索引,形成 (University id #, Year) × fin_element 的双层行索引;
- sort_index(axis=1) 确保列顺序符合业务预期(如 prior_year 在左、current_year 在右);
- 最终 reset_index() 输出扁平化 DataFrame,完全匹配目标格式。
⚠️ 注意事项:
- 若原始数据中 financial_period 值存在缺失或非唯一组合,unstack 可能报错 ValueError: Index contains duplicate entries,建议先校验:df.duplicated(['University id #', 'Year', 'financial_period']).any();
- 列名含空格或特殊字符(如 element #1)不影响操作,但建议生产环境统一使用下划线命名(如 element_1)提升可读性与兼容性;
- 此方法天然支持任意数量的 element 列和 financial_period 类别,无需硬编码列名,扩展性强。
该模式是 Pandas 高级重塑的典型范式,适用于财务报表、KPI 对比、多维度指标分析等场景,远比嵌套 melt + pivot_table 更稳健、更易维护。











