You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:51:20