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

Python Pandas 将堆叠格式列转换为长表格式实现方法

复合表头CSV转长表实现方案

核心问题出在原始文件是三层堆叠表头,直接用melt/pivot/transpose硬转没有先规整表头信息,自然拿不到正确结果。按以下步骤处理即可:

处理逻辑

  • 先拆分三层表头:最上层年份是读入DF默认的列名(空值列被pandas自动命名为Unnamed),中间层是月份、最下层是出口指标,两层都存在跨列空值,用向前填充补全每一列对应的年份、月份、指标三元组。
  • 剔除前3行无效的表头、空行,提取真实业务数据,前两列固定为编码、国家。
  • 先把宽表转成长表,拆分出年份、月份、指标字段,再把两个出口指标透视成独立列,最后做字段清理即可。

可直接运行的代码

import pandas as pd
import numpy as np

# 原始DF构造代码(读本地CSV时替换这部分为pd.read_csv即可)
df = pd.DataFrame([{'Unnamed: 0': np.nan, 'Unnamed: 1': np.nan, '2017': 'Enero', 'Unnamed: 3': np.nan, 'Unnamed: 4': 'Febrero', 'Unnamed: 5': np.nan}, {'Unnamed: 0': np.nan, 'Unnamed: 1': np.nan, '2017': 'Valor export', 'Unnamed: 3': 'Volumen export', 'Unnamed: 4': 'Valor export', 'Unnamed: 5': 'Volumen export'}, {'Unnamed: 0': np.nan, 'Unnamed: 1': np.nan, '2017': np.nan, 'Unnamed: 3': np.nan, 'Unnamed: 4': np.nan, 'Unnamed: 5': np.nan}, {'Unnamed: 0': '080390110000 SA-2017', 'Unnamed: 1': 'USA', '2017': '29200.10725', 'Unnamed: 3': '67198.189', 'Unnamed: 4': '38631.16383', 'Unnamed: 5': '87962.196'}, {'Unnamed: 0': '090390110000 SA-2017', 'Unnamed: 1': 'Mexico', '2017': '9283.79255', 'Unnamed: 3': '21638.126', 'Unnamed: 4': '9785.40009', 'Unnamed: 5': '22863.867'}, {'Unnamed: 0': '010390110000 SA-2017 ', 'Unnamed: 1': 'Canada', '2017': '8017.55675', 'Unnamed: 3': '19352.178', 'Unnamed: 4': '11137.27057', 'Unnamed: 5': '27020.428'}, {'Unnamed: 0': '070390110000 SA-2017', 'Unnamed: 1': 'Brazil', '2017': '3786.44363', 'Unnamed: 3': '8704.871', 'Unnamed: 4': '4553.70795', 'Unnamed: 5': '10583.833'}, {'Unnamed: 0': '060390110000 SA-2017', 'Unnamed: 1': 'Italy', '2017': '4809.76636', 'Unnamed: 3': '12411.691', 'Unnamed: 4': '4304.02052', 'Unnamed: 5': '11198.063'}, {'Unnamed: 0': '000390110000 SA-2017  ', 'Unnamed: 1': 'Spain', '2017': '2290.65793', 'Unnamed: 3': '6227.269', 'Unnamed: 4': '3269.41957', 'Unnamed: 5': '9118.595'}, {'Unnamed: 0': '0990390110000 SA-2017  ', 'Unnamed: 1': 'Costa Rica', '2017': '1855.70035', 'Unnamed: 3': '4687.714', 'Unnamed: 4': '2668.57892', 'Unnamed: 5': '6425.365'}, {'Unnamed: 0': '0040390110000 SA-2017 ', 'Unnamed: 1': 'Honduras', '2017': '1823.358', 'Unnamed: 3': '4223.521', 'Unnamed: 4': '250.2036', 'Unnamed: 5': '603.392'}])

# 1. 提取三层表头,向前填充补全跨列空值
header_year = pd.Series(df.columns).ffill()
header_month = df.iloc[0].ffill().reset_index(drop=True)
header_metric = df.iloc[1].reset_index(drop=True)

# 2. 提取真实数据行,重命名列
data = df.iloc[3:].reset_index(drop=True)
new_cols = ['编码', '国家']
for col_idx in range(2, len(header_year)):
    new_cols.append(f"{header_year[col_idx]}_{header_month[col_idx]}_{header_metric[col_idx]}")
data.columns = new_cols

# 3. 宽表转长表,拆分字段后透视指标
long_df = data.melt(id_vars=['编码', '国家'], var_name='col_meta', value_name='value')
long_df[['年份', '月份', '指标']] = long_df['col_meta'].str.split('_', expand=True)
long_df = long_df.pivot(
    index=['编码', '国家', '年份', '月份'],
    columns='指标',
    values='value'
).reset_index()

# 4. 字段清理:去除编码前后空格、数值转浮点
long_df['编码'] = long_df['编码'].str.strip()
long_df[['Valor export', 'Volumen export']] = long_df[['Valor export', 'Volumen export']].astype(float)

说明

  • 最终输出的long_df就是要求的长表格式,每行对应唯一的国家、编码、年份、月份组合,Valor export和Volumen export各为独立列,列顺序可按需调整。
  • 如果原始CSV包含更多年份、月份,只要表头结构和样例一致(年份、月份各跨2列,第三层表头为两个出口指标),代码无需修改可直接运行,向前填充逻辑会自动补全所有列的属性。

内容的提问来源于stack exchange,提问作者JoshPickel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:39:57