Python/Pandas如何实现多层表头多维宽表unstack/melt转长表
Pandas多层复合表头逆透视转标准长表方案
处理三层维度+多年份的复合表头宽表,优先用stack处理MultiIndex,比melt、wide_to_long代码量少、容错率高,再复杂的多层级表都能通用。
前置准备:正确读入带复合表头的表格
读文件时不要手动改列名,直接指定表头行号让Pandas自动生成多层列索引,这步是后续转换不出错的核心:
import pandas as pd # header参数填你复合表头占据的行序号,比如表头在Excel第1-3行(对应索引0、1、2)就传[0,1,2] df = pd.read_excel("你的多维表格路径.xlsx", header=[0,1,2]) # 执行完打印列名确认结构,正常会输出MultiIndex类型,层级对应你表的维度取值 print(df.columns)
常见列结构分两类,对应不同转换代码,直接套就行:
转换代码(直接复用)
场景1:年份在列头最顶层(列共4层索引:年份→性别→年龄→城乡)
把所有列层级一次性压成行维度,重置索引后直接得到长表:
# level参数按列的层级顺序填,dropna=False避免缺失值的维度组合被自动过滤 long_df = df.stack(level=[0,1,2,3], dropna=False).reset_index() # 按你压栈的层级顺序重命名字段即可,若表最左侧有其他行维度(比如地区、指标名),在最前面加对应列名 long_df.columns = ["year", "male_female", "adult_youth", "urban_rural", "Value"]
场景2:年份是独立列(列共3层索引:性别→年龄→城乡,行维度存年份)
先把年份设为行索引再压列层级:
long_df = df.set_index("year").stack(level=[0,1,2], dropna=False).reset_index() long_df.columns = ["year", "male_female", "adult_youth", "urban_rural", "Value"]
踩坑说明
- 不推荐优先用
melt/wide_to_long:这两个方法处理单层列头更方便,多层列头需要手动写正则拆分列名,列数多、维度值有特殊字符时很容易匹配错误,stack是Pandas原生适配多层索引的方法,性能和准确率都更高 - 必须加
dropna=False:stack默认会把全为空值的维度组合直接删除,业务表经常存在维度组合无数据的情况,不加这个参数会丢记录 - 列层级顺序不对不用手动调整:如果你的列层级顺序是城乡→年龄→性别,只要调整
level参数里的顺序,重命名时对应好字段名即可,不用提前改列结构 - 转换完取前5行
print(long_df.head())核对维度取值,确认无误就可以直接接pivot_table、crosstab做后续分析
内容的提问来源于stack exchange,提问作者legojenn
相关产品推荐
相关产品推荐

