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

如何将指定结构的Pandas DataFrame熔解转换为目标长表格式?

解决宽表转长表的Pandas操作

嘿,这个需求其实就是典型的宽格式DataFrame转长格式场景,我给你提供两种简洁的实现方法,你可以根据自己的习惯选择:

方法一:拆分后合并(直观易懂)

这种方法思路直接:把prod1和prod2对应的列分别提取出来,重命名成目标格式,再合并到一起,新手也能快速理解。

import pandas as pd

# 原始数据
df = pd.DataFrame({'custid':[1,2,3,4],
                   'prod1':['jeans','tshirt','jacket','tshirt'],
                   'prod1_hnode1':[1,2,3,2],
                   'prod1_hnode2':[6,7,8,7],
                   'prod2':['tshirt','jeans','jacket','shirt'],
                   'prod2_hnode1':[2,1,3,4],
                   'prod2_hnode2':[7,6,8,7]})

# 处理prod1组:重命名列并添加prod标识
prod1_part = df[['custid', 'prod1', 'prod1_hnode1', 'prod1_hnode2']].rename(
    columns={'prod1': 'rec', 'prod1_hnode1': 'hnode1', 'prod1_hnode2': 'hnode2'}
)
prod1_part['prod'] = 'prod1'

# 处理prod2组:同样重命名列并添加prod标识
prod2_part = df[['custid', 'prod2', 'prod2_hnode1', 'prod2_hnode2']].rename(
    columns={'prod2': 'rec', 'prod2_hnode1': 'hnode1', 'prod2_hnode2': 'hnode2'}
)
prod2_part['prod'] = 'prod2'

# 合并两个部分并按custid排序
dfnew = pd.concat([prod1_part, prod2_part], ignore_index=True)
dfnew = dfnew.sort_values('custid').reset_index(drop=True)

# 调整列顺序和目标格式一致
dfnew = dfnew[['custid', 'prod', 'rec', 'hnode1', 'hnode2']]
print(dfnew)

运行后得到的结果完全符合你的要求:

custid  prod     rec  hnode1  hnode2
0       1  prod1   jeans       1       6
1       1  prod2  tshirt       2       7
2       2  prod1  tshirt       2       7
3       2  prod2   jeans       1       6
4       3  prod1  jacket       3       8
5       3  prod2  jacket       3       8
6       4  prod1  tshirt       2       7
7       4  prod2   shirt       4       7

方法二:使用pd.wide_to_long()(专业高效)

Pandas专门提供了wide_to_long()函数来处理这种带编号前缀的宽表转长表场景,代码更简洁,适合处理更复杂的多组列转换需求。

import pandas as pd

# 原始数据
df = pd.DataFrame({'custid':[1,2,3,4],
                   'prod1':['jeans','tshirt','jacket','tshirt'],
                   'prod1_hnode1':[1,2,3,2],
                   'prod1_hnode2':[6,7,8,7],
                   'prod2':['tshirt','jeans','jacket','shirt'],
                   'prod2_hnode1':[2,1,3,4],
                   'prod2_hnode2':[7,6,8,7]})

# 先重命名列,让列名符合wide_to_long的格式:{字段名}_{prod编号}
df_renamed = df.rename(columns={
    'prod1': 'rec_1',
    'prod1_hnode1': 'hnode1_1',
    'prod1_hnode2': 'hnode2_1',
    'prod2': 'rec_2',
    'prod2_hnode1': 'hnode1_2',
    'prod2_hnode2': 'hnode2_2'
})

# 使用wide_to_long转长表
dfnew = pd.wide_to_long(
    df_renamed,
    stubnames=['rec', 'hnode1', 'hnode2'],  # 对应目标表的字段名
    i='custid',  # 标识符列(保留不变的列)
    j='prod_num',  # 从列名中提取的prod编号
    sep='_',  # 列名中字段和编号的分隔符
    suffix='\\d+'  # 匹配编号的正则(这里匹配数字)
).reset_index()

# 把prod_num转换成目标格式的prod1/prod2
dfnew['prod'] = 'prod' + dfnew['prod_num'].astype(str)

# 调整列顺序并删除临时列
dfnew = dfnew[['custid', 'prod', 'rec', 'hnode1', 'hnode2']].drop('prod_num', axis=1)
print(dfnew)

这个方法的结果和方法一完全一致,处理大规模数据时效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:02:07