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

如何用Pandas处理多索引表头并转换为长格式?

问题:带合并单元格多级表头的Excel转长格式数据

现有包含信用利差的Excel文件,表头为合并单元格形成的多级结构,示例结构如下:

USD All Sectors A  USD All Sectors A  USD All Sectors A
Level  Date        1D                7D                14D
0      05/30/2023  66.42             66.42             66.42
0      05/31/2023  65.95             65.95             65.95

需要将其转换为如下长格式:

DATO        INDEKS            TENOR  NIVEAU
05/30/2023  USD All Sectors A  1D     66.42
05/31/2023  USD All Sectors A  1D     65.95
05/30/2023  USD All Sectors A  7D     66.42
05/31/2023  USD All Sectors A  7D     65.95
05/30/2023  USD All Sectors A  14D    66.42
05/31/2023  USD All Sectors A  14D    65.95

尝试了以下代码,输出不符合预期,问题出在多级表头处理不当:

import pandas as pd

# Load the data from the Excel file
data = pd.read_excel('credit_spreads.xlsx', header=[0, 1], skiprows=12)

df_stacked = df.stack(level=1).reset_index()
print(df_stacked.head(10))

疑问:stack是否是正确的函数?还是应该用melt或pivot?


解决方案

核心问题分析

你的Excel表头中,前两列(Level、Date)的第一级表头为空(合并单元格导致),后续列的第一级是指数名称(INDEKS)、第二级是期限(TENOR)。直接用stack会因为前两列的多级索引结构混乱导致结果错误,需要先分离元数据列和数据列,再进行格式转换。

方法一:使用stack(贴合多级表头场景)

import pandas as pd

# 读取Excel,指定两行作为多级表头
df = pd.read_excel('credit_spreads.xlsx', header=[0, 1], skiprows=12)

# 给前两列的第一级表头统一命名,方便分离
df.columns = df.columns.set_levels(['Meta', 'Meta'] + list(df.columns.levels[0][2:]), level=0)

# 提取元数据列(Level、Date)和数据列
meta_df = df['Meta'].reset_index(drop=True)
data_df = df.drop('Meta', axis=1)

# 将数据列的第二级表头(TENOR)转为行,得到长格式
stacked_data = data_df.stack(level=1).reset_index()

# 重命名列并合并元数据
stacked_data.columns = ['行索引', 'INDEKS', 'TENOR', 'NIVEAU']
final_df = pd.concat([meta_df.loc[stacked_data['行索引']], stacked_data.drop('行索引', axis=1)], axis=1)

# 调整列顺序、重命名并删除冗余列
final_df = final_df[['Date', 'INDEKS', 'TENOR', 'NIVEAU']].rename(columns={'Date': 'DATO'})
final_df = final_df.drop('Level', axis=1)

print(final_df)

方法二:使用melt(直观的列转行操作)

import pandas as pd

# 读取Excel,指定两行作为多级表头
df = pd.read_excel('credit_spreads.xlsx', header=[0, 1], skiprows=12)

# 将多级列名合并为单级,方便后续拆分
df.columns = [f"{col[0]}_{col[1]}" if col[0] is not None else col[1] for col in df.columns]

# 将数据列转为行,保留Level和Date作为标识列
melted_df = pd.melt(df, id_vars=['Level', 'Date'], var_name='INDEKS_TENOR', value_name='NIVEAU')

# 拆分合并的列名为INDEKS和TENOR
melted_df[['INDEKS', 'TENOR']] = melted_df['INDEKS_TENOR'].str.split('_', expand=True)

# 调整列顺序、重命名并删除冗余列
final_df = melted_df[['Date', 'INDEKS', 'TENOR', 'NIVEAU']].rename(columns={'Date': 'DATO'})
final_df = final_df.drop('Level', axis=1)

print(final_df)

总结

  • stack更适合处理原生多级表头的场景,只要先分离非数据类的表头列即可;
  • melt操作更直观,适合将普通列转为行,需要先把多级列名合并再拆分;
  • 两种方法都能实现目标格式,可根据个人习惯选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:14:51