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

如何用Pandas将多行转列并整理含复合表头的Excel数据?

Pandas处理复合表头Excel的多行转列解决方案

问题描述

读取的复合表头Excel结构如下:

ori code   cgk       cgk    clg       clg
                              ori city   jakarta   NaN    cilegon   NaN
                              ori prop   jakarta   NaN    banten    NaN
                              ori area   jawa      NaN    jawa      NaN

code    city       district   island    type a     days    type b    days
001     jakarta    jakarta     jawa      12000       2      13000      3
002     surabaya   surabaya    jawa      13000       3      14000      4

需要转换为目标格式:

code   city        district    island    type       price_type   days    ori_code   ori_city     ori_prop   ori_area
001    jakarta     jakarta     jawa      type a     12000         2         cgk     jakarta    jakarta      jawa
001    jakarta     jakarta     jawa      type b     13000         3         clg     cilegon    banten       jawa 
002    surabaya    surabaya    jawa      type a     13000         3         cgk     jakarta    jakarta      jawa
002    surabaya    surabaya    jawa      type b     14000         4         clg     cilegon    banten       jawa

已执行操作:

df = df.set_index(['code','city','district','island'])

分步解决方案

1. 提取ori信息映射表

首先从复合表头的前4行提取cgk和clg对应的ori属性映射:

# 假设读取Excel时指定header=[0,1,2,3]来加载复合表头
# 构建ori信息映射字典
ori_mapping = {}
for ori_code in ['cgk', 'clg']:
    # 遍历4层表头,提取对应属性
    ori_info = {
        'ori_code': ori_code,
        'ori_city': df.columns.get_level_values(1)[df.columns.get_level_values(0) == ori_code][0],
        'ori_prop': df.columns.get_level_values(2)[df.columns.get_level_values(0) == ori_code][0],
        'ori_area': df.columns.get_level_values(3)[df.columns.get_level_values(0) == ori_code][0]
    }
    ori_mapping[ori_code] = ori_info

2. 拆分并融合type与days列

先重置索引,再通过melt和pivot来拆分type/days列,关联ori信息:

# 重置索引,恢复基础列
df_reset = df.reset_index()

# 拆分多列为行,保留基础列作为id
melted = df_reset.melt(
    id_vars=['code', 'city', 'district', 'island'],
    var_name=['ori_col', 'col_type'],
    value_name='content'
)

# 区分price_type和days类别,提取type名称
melted['category'] = melted['col_type'].map(lambda x: 'price_type' if 'type' in x else 'days')
melted['type'] = melted['col_type'].where(melted['col_type'].str.contains('type'), None)

# 旋转表格,将price_type和days转为列
pivoted = melted.pivot_table(
    index=['code', 'city', 'district', 'island', 'ori_col', 'type'],
    columns='category',
    values='content',
    aggfunc='first'
).reset_index()

# 填充同一组内的type空值(days行对应同组的type)
pivoted['type'] = pivoted.groupby(['code', 'city', 'district', 'island', 'ori_col'])['type'].ffill().bfill()

# 关联ori映射表,添加ori属性列
pivoted = pivoted.merge(
    pd.DataFrame.from_dict(ori_mapping, orient='index').reset_index().rename(columns={'index': 'ori_col'}),
    on='ori_col',
    how='left'
)

3. 调整列顺序并输出结果

最后调整列顺序匹配目标格式:

# 按目标顺序排列列
final_df = pivoted[[
    'code', 'city', 'district', 'island', 'type', 'price_type', 'days',
    'ori_code', 'ori_city', 'ori_prop', 'ori_area'
]]

# 查看结果
print(final_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:15:30