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

pandas宽表转长表:非标准列名适配wide_to_long方案

Pandas宽表转长表:适配「数字_字段名」列名的解决方案

原始数据与目标格式

原始宽表结构

import pandas as pd

data = [['Tom', 'run', '2022-01-26', 'run', '2027-01-26'], 
        ['Max', 'stop', '2020-11-16', 'run', '2022-04-26'], 
        ['Bob', 'run', '2021-10-03', 'stop', '2022-01-26'], 
        ['Ben', 'run', '2020-03-11', 'stop', '2013-01-26'], 
        ['Eva', 'stop', '2017-11-16', 'run', '2015-01-26']]
df = pd.DataFrame(data, columns=['Patient', '1_Action', '1_Time', '2_Action', '2_Time'])

目标长表格式

Patient action        time
0    Tom    run  2022-01-26
1    Max   stop  2020-11-16
2    Bob    run  2021-10-03
3    Ben    run  2020-03-11
4    Eva   stop  2017-11-16
5    Tom    run  2027-01-26
6    Max    run  2022-04-26
7    Bob   stop  2022-01-26
8    Ben   stop  2013-01-26
9    Eva    run  2015-01-26

问题说明

尝试使用pd.wide_to_long()时,因原始列名是「数字_字段名」(如1_Action),而该函数默认预期「字段名_数字」格式(如action_1),导致报错ValueError: the id variables need to uniquely identify each row。由于列数较多(约45列),无法手动修改列名,需批量处理或调整代码。

解决方案

方案1:批量修改列名适配wide_to_long

通过字符串处理反转列名中的数字和字段名部分,再使用原逻辑:

# 批量重命名列:将「数字_字段名」转为「字段名_数字」,保留Patient列
df.columns = ['Patient'] + [f"{col.split('_')[1].lower()}_{col.split('_')[0]}" for col in df.columns[1:]]

# 调用wide_to_long并整理结果
df_long = pd.wide_to_long(df, 
                          stubnames=['action', 'time'],
                          i='Patient',
                          j='num',
                          sep='_').reset_index(drop=True)

方案2:直接使用melt处理原列名

无需修改列名,通过分组拆分动作和时间字段后合并:

# 筛选动作列和时间列
action_cols = [col for col in df.columns if 'Action' in col]
time_cols = [col for col in df.columns if 'Time' in col]

# 分别转换动作和时间数据为长格式
df_action = df.melt(id_vars='Patient', value_vars=action_cols, var_name='num', value_name='action')
df_time = df.melt(id_vars='Patient', value_vars=time_cols, var_name='num', value_name='time')

# 合并并清理冗余列
df_long = pd.merge(df_action, df_time, on=['Patient', 'num'])
df_long = df_long.drop('num', axis=1).sort_values('Patient').reset_index(drop=True)

两种方案均可生成目标长表格式,方案1贴合wide_to_long的原生逻辑,方案2无需改动原始列结构,适合需要保留原列名的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:40:39