如何使用pandas将多层索引列展开为独立列并转换为长表格式
pandas多层列索引宽表转指定结构长表实现方案
针对列是两层MultiIndex、行索引为Date的DataFrame,直接使用stack方法转换层级即可,无需循环处理,实现简洁且执行效率高。
实现代码
1. (可选)构造测试数据
先构造和你给出的示例结构完全一致的测试DataFrame,方便对照验证:
import pandas as pd # 定义索引和列层级 date_index = pd.Index([2020, 2021, 2022], name="Date") col_level1 = ["Close", "Open"] col_level2 = ["AAP", "AWS", "BGG"] multi_cols = pd.MultiIndex.from_product([col_level1, col_level2], names=["metric", "ticker"]) # 填入示例数值 demo_data = [ [10, 50, 13, 100, 500, 13], [11, 41, 7, 111, 41, 7], [12, 50, 13, 122, 50, 13] ] df = pd.DataFrame(demo_data, index=date_index, columns=multi_cols)
2. 核心转换代码
# 将第二层列索引转为行维度,保留第一层列作为指标字段 df_long = df.stack(level=1, future_stack=True).reset_index() # 将存储原二级列值的列重命名为要求的Index2 df_long.rename(columns={"ticker": "Index2"}, inplace=True) # 调整列顺序匹配输出要求 df_long = df_long[["Date", "Close", "Open", "Index2"]]
输出结果
执行后得到的长表结构和你要求完全一致:
Date Close Open Index2 0 2020 10 100 AAP 1 2020 50 500 AWS 2 2020 13 13 BGG 3 2021 11 111 AAP 4 2021 41 41 AWS 5 2021 7 7 BGG 6 2022 12 122 AAP 7 2022 50 50 AWS 8 2022 13 13 BGG
注意事项
- 参数
future_stack=True用于适配pandas 2.0及以上版本的新stack逻辑,避免版本兼容警告,如果你使用的pandas版本低于2.0,可直接删除该参数,转换效果完全相同。 - 如果你的第一层列除Close、Open外还有High、Low、Volume等其他指标字段,该代码无需修改,会自动保留所有一级指标列,不需要手动枚举字段名。
level=1代表选择列索引的第二层进行转换,如果你给二级列索引设置了名称(比如示例里的ticker),也可以写成level="ticker",可读性更强。
内容的提问来源于stack exchange,提问作者Mikul
相关产品推荐
相关产品推荐

