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

基于需求将Pandas DataFrame多列转置为多行的实现方法

Pandas宽表转长表:Fee/Amount列多行展开实现方法

原始DataFrame

ID    Name     Fee1  Amount1  Fee2  Amount2  Fee3   Amount3
1     Abc       05     100     06     115     15      50
2     Def       12     215     07     215     08      60
3     Ghi       17     120     05     60      06      80
4     Jkl       03     310     06     150     15      55

目标DataFrame

ID    Name     Fee  Amount
1     Abc       05     100
1     Abc       06     115
1     Abc       15      50
2     Def       12     215
2     Def       07     215
2     Def       08      60
3     Ghi       17     120
3     Ghi       05      60
3     Ghi       06      80
4     Jkl       03     310
4     Jkl       06     150
4     Jkl       15      55

方法1:使用pd.wide_to_long(推荐)

这是Pandas专门为带编号后缀的重复列设计的转换工具,代码简洁高效:

import pandas as pd

# 构造原始数据(已有df1可跳过此步)
df1 = pd.DataFrame({
    'ID': [1,2,3,4],
    'Name': ['Abc','Def','Ghi','Jkl'],
    'Fee1': ['05','12','17','03'],
    'Amount1': [100,215,120,310],
    'Fee2': ['06','07','05','06'],
    'Amount2': [115,215,60,150],
    'Fee3': ['15','08','06','15'],
    'Amount3': [50,60,80,55]
})

# 执行转换
result = pd.wide_to_long(
    df1,
    stubnames=['Fee', 'Amount'],  # 要展开的列前缀
    i=['ID', 'Name'],             # 保持不变的标识列
    j='seq',                      # 临时生成的编号列名称
    sep=''                        # 列名中前缀与编号的分隔符(此处无分隔符)
).reset_index(drop=False)

# 删除临时编号列,得到目标格式
result = result.drop('seq', axis=1)
print(result)

方法2:使用melt+pivot_table

适合需要自定义处理逻辑的场景,先熔解再重组:

# 第一步:将Fee/Amount列熔化为行
melted = df1.melt(id_vars=['ID', 'Name'], var_name='col_type', value_name='value')

# 第二步:从列名提取类型(Fee/Amount)和编号
melted[['type', 'num']] = melted['col_type'].str.extract(r'(\D+)(\d+)')

# 第三步:透视重组,将Fee和Amount转为列
result = melted.pivot_table(
    index=['ID', 'Name', 'num'],
    columns='type',
    values='value',
    aggfunc='first'
).reset_index().drop('num', axis=1)

# 调整列顺序与名称
result = result[['ID', 'Name', 'Fee', 'Amount']]
print(result)

方法3:使用多层列索引+stack

通过构建多层列索引,再展开重复维度:

# 第一步:构建多层列索引
new_cols = []
for col in df1.columns:
    if col.startswith('Fee') or col.startswith('Amount'):
        new_cols.append((col[:-1], col[-1]))
    else:
        new_cols.append((col, ''))
df1.columns = pd.MultiIndex.from_tuples(new_cols)

# 第二步:设置标识列为索引,展开编号维度
result = df1.set_index(['ID', 'Name']).stack(level=1, dropna=False).reset_index(level=2, drop=True)

# 第三步:重置索引并修正列名
result = result.reset_index()
result.columns = ['ID', 'Name', 'Fee', 'Amount']
print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 12:23:17