本文介绍如何将 pandas 透视表(pivot_table)生成的多级列索引(multiindex columns)高效展平为单层列名,例如将 `(''value1'', ''a'')` 转换为 `''a_value2''`,并重置索引以获得结构清晰、可直接用于建模或导出的宽格式 dataframe。
在使用 pd.pivot_table() 处理长格式数据时,若指定多个 values 列(如 [''value1'', ''value2''])和一个 columns 维度(如 ''Category''),pandas 会自动创建双层列索引:外层为 value 字段名,内层为 category 取值。这种结构虽利于分组查看,但不便于后续分析、写入数据库或机器学习特征工程——此时需将其“展平”(flatten)为语义明确的单层列名。
核心步骤分为两步:
重命名多级列为扁平字符串:利用 table.columns.to_flat_index() 获取所有 (value_field, category) 元组,再通过列表推导式构造新列名(推荐按 category_value 格式,更符合直觉且避免列名冲突);
重置行索引:调用 reset_index() 将原 IDNum 索引转为普通列,确保最终结果为标准二维表格。
以下是完整可运行示例:
复制AI写代码
import pandas as pd
# 构造原始数据
df = pd.DataFrame({
''IDNum'': [1, 1, 2, 3, 3, 4],
''Category'': [''a'', ''b'', ''a'', ''c'', ''b'', ''b''],
''value1'': [1.5, 2.2, 3.6, 5.1, 6.0, 1.0],
''value2'': [2.0, 3.6, 4.5, 8.2, 6.1, 1.2]
})
# 创建透视表(产生 MultiIndex columns)
table = pd.pivot_table(
df,
values=[''value1'', ''value2''],
index=''IDNum'',
columns=''Category''
)
# ✅ 关键:展平列名 —— 按 "Category_Value" 格式重组
table.columns = [f"{col[1]}_{col[0]}" for col in table.columns.to_flat_index()]
# ✅ 关键:将 IDNum 索引转为普通列
table = table.reset_index()
print(table)
输出结果:
复制AI写代码
IDNum a_value1 b_value1 c_value1 a_value2 b_value2 c_value2
0 1 1.5 2.2 NaN 2.0 3.6 NaN
1 2 3.6 NaN NaN 4.5 NaN NaN
2 3 NaN 6.0 5.1 NaN 6.1 8.2
3 4 NaN 1.0 NaN NaN 1.2 NaN
⚠️ 注意事项:
列名顺序由 to_flat_index() 返回顺序决定,其默认排序为外层升序 → 内层升序(即先排 value1 下所有 category,再排 value2)。若需自定义顺序(如按 category 分组聚合),建议在 pivot_table 中显式传入 columns=pd.Categorical(..., ordered=True);
若原始数据中存在重复 (IDNum, Category) 组合,pivot_table 默认使用 np.mean 聚合,可改用 aggfunc=''first'' 或 lambda x: x.iloc[0] 避免意外均值;
替代方案:也可使用 df.pivot(index=''IDNum'', columns=''Category'', values=[''value1'',''value2'']),但 pivot 不支持多 values,需分别 pivot 后 pd.concat(..., axis=1),灵活性与健壮性不如 pivot_table + flatten 组合。
该方法简洁、通用,是将长表→宽表转换中处理多指标透视的标准化实践。


