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

如何重塑包含重复列名的DataFrame?

解决方法

你要把宽格式的DataFrame转成长格式,melt其实是合适的方法,但问题出在原DataFrame有重复列名,得先处理列名再操作。以下是具体步骤:

1. 先处理重复列名

原DataFrame里有重复的SITE和LAL列,先给它们加个后缀区分开:

import pandas as pd

# 模拟你的dataframe_1
data = {
    'week': [1,2,3],
    'SITE': ['BARTON CHAPEL', 'BARTON CHAPEL', 'BARTON CHAPEL'],
    'LAL': [1.1, 1.1, 1.1],
    'SITE': ['PENASCAL I', 'PENASCAL I', 'PENASCAL I'],
    'LAL': [1, 1, 1]
}
df = pd.DataFrame(data)
# 重命名重复列
df.columns = ['week', 'SITE_1', 'LAL_1', 'SITE_2', 'LAL_2']

2. 拆分合并数据(两种简单方法)

方法一:拆分两组数据后拼接

直接把两组SITE-LAL数据拆出来,重命名列后拼在一起:

# 第一组数据
df1 = df[['week', 'SITE_1', 'LAL_1']].rename(columns={'SITE_1':'SITE', 'LAL_1':'LAL'})
# 第二组数据
df2 = df[['week', 'SITE_2', 'LAL_2']].rename(columns={'SITE_2':'SITE', 'LAL_2':'LAL'})
# 合并成最终结果
df_result = pd.concat([df1, df2], ignore_index=True)

方法二:用pd.wide_to_long一步到位

这个方法专门处理这种多组重复列的宽转长场景:

df_result = pd.wide_to_long(df, stubnames=['SITE', 'LAL'], i='week', j='group').reset_index(drop=True)

运行后得到的df_result就是你要的dataframe_2:

week           SITE  LAL
0     1  BARTON CHAPEL  1.1
1     2  BARTON CHAPEL  1.1
2     3  BARTON CHAPEL  1.1
3     1     PENASCAL I  1.0
4     2     PENASCAL I  1.0
5     3     PENASCAL I  1.0

为啥之前用melt没成功?

原DataFrame的重复列名会让melt没法正确识别分组,要是非要用melt,得先给列名加唯一标识,再通过后续步骤重组,步骤会繁琐一些:

# 重命名列后用melt
df_melted = df.melt(id_vars='week', 
                    value_vars=['SITE_1', 'LAL_1', 'SITE_2', 'LAL_2'],
                    var_name='type',
                    value_name='value')
# 拆分类型和分组,再重组
df_result = df_melted.assign(group=df_melted['type'].str.split('_').str[1])\
                     .pivot(index=['week', 'group'], columns='type', values='value')\
                     .reset_index(drop=True)\
                     .rename(columns={'SITE_1':'SITE', 'LAL_1':'LAL'})

所以更推荐前面两种简单的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:22:42