如何将带复合表头的Pandas DataFrame转换为规范表格?
Pandas DataFrame 格式转换解决方案
需求说明
需要将如下格式的DataFrame:
| index | 0 | 1 | 2 | 3 | 4 | ... |
|---|---|---|---|---|---|---|
| 0 | parameter | 2001 | 2001 | 2002 | 2002 | ... |
| 1 | low | high | low | high | ... | |
| 2 | foo | 1 | 2 | 7 | 8 | ... |
| 3 | bar | NaN | NaN | 12 | 13 | ... |
转换为:
| index | parameter | year | low | high | ... |
|---|---|---|---|---|---|
| 0 | foo | 2001 | 1 | 2 | ... |
| 1 | foo | 2002 | 7 | 8 | ... |
| 2 | bar | 2002 | 12 | 13 | ... |
完整转换代码
import pandas as pd import numpy as np data = { 0: ['parameter', '', 'foo', 'bar'], 1: [2001, 'low', 1, np.nan], 2: [2001, 'high', 2, np.nan], 3: [2002, 'low', 7, 12], 4: [2002, 'high', 8, 13], } df = pd.DataFrame(data) # 1. 构建列的MultiIndex:年份 + 高低值层级 year_level = df.iloc[0, 1:].values # 提取第一行的年份数据(跳过第一列) type_level = df.iloc[1, 1:].values # 提取第二行的low/high标识 multi_cols = pd.MultiIndex.from_arrays([year_level, type_level], names=['year', 'type']) # 2. 清理数据主体,匹配新列名 df_clean = df.iloc[2:] # 保留实际参数和数值行 df_clean.columns = ['parameter'] + list(multi_cols) # 3. 宽表转长表后透视,得到目标格式 df_melted = df_clean.melt(id_vars='parameter', var_name=['year', 'type'], value_name='value') df_melted = df_melted.dropna(subset=['value']) # 移除空值行 df_result = df_melted.pivot_table(index=['parameter', 'year'], columns='type', values='value', aggfunc='first').reset_index() # 整理最终格式 df_result.columns.name = None df_result = df_result[['parameter', 'year', 'low', 'high']] print(df_result)
关键步骤说明
- 构建多层列索引:用原始表前两行的年份、高低值标识作为列的层级,明确每列数据的含义。
- 数据主体清理:跳过表头行,给剩余数据匹配新的列名体系。
- 宽转长+透视:通过
melt将多列的年份和类型拆分为行数据,再用pivot_table将low/high转为独立列,自动过滤空值后得到目标结构。
内容的提问来源于stack exchange,提问作者Wasserwaage
相关产品推荐
相关产品推荐

