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

如何让pandas的wide_to_long()识别列名末尾的存根而非开头?

解决列名格式为「年份_存根」的宽表转长表问题

针对你遇到的列名是2010_A(weekly)这种「年份在前、存根在后」的格式,pd.wide_to_long确实没有直接参数支持反向识别存根,但可以通过两种简单方法实现需求:

方法一:先重命名列,再用wide_to_long

先把列名的年份和存根位置调换,变成wide_to_long能识别的「存根_年份」格式,再调用函数:

import numpy as np
import pandas as pd

np.random.seed(0)
df = pd.DataFrame({'2010_A(weekly)': np.random.rand(3),
                   '2011_A(weekly)': np.random.rand(3),
                   '2010_B(weekly)': np.random.rand(3),
                   '2011_B(weekly)': np.random.rand(3),
                   'X' : np.random.randint(3, size=3)})
df['id'] = df.index

# 重命名列:将"年份_存根"转为"存根_年份"
df_renamed = df.rename(columns=lambda x: '_'.join(x.split('_', 1)[::-1]) if '_' in x else x)

# 调用wide_to_long
result = pd.wide_to_long(df_renamed, ['A(weekly)', 'B(weekly)'], i='id', j='year', sep='_')
# 重置索引得到目标列顺序
result = result.reset_index()[['id', 'year', 'X', 'A(weekly)', 'B(weekly)']]

方法二:用melt+提取列信息+pivot实现

如果存根名称里可能包含下划线,这种方法更通用:

import numpy as np
import pandas as pd

np.random.seed(0)
df = pd.DataFrame({'2010_A(weekly)': np.random.rand(3),
                   '2011_A(weekly)': np.random.rand(3),
                   '2010_B(weekly)': np.random.rand(3),
                   '2011_B(weekly)': np.random.rand(3),
                   'X' : np.random.randint(3, size=3)})
df['id'] = df.index

# 第一步:将宽表melt为长表,保留id和X作为标识
melted = df.melt(id_vars=['id', 'X'], var_name='col_name', value_name='value')

# 第二步:从列名中提取年份和存根
melted[['year', 'stub']] = melted['col_name'].str.extract(r'(\d+)_(.+)', expand=True)

# 第三步:pivot将存根转为列,得到目标格式
result = melted.pivot(index=['id', 'year', 'X'], columns='stub', values='value').reset_index()
result.columns.name = None  # 去掉列名的索引标识

两种方法最终都能得到包含id, year, X, A(weekly), B(weekly)的长格式DataFrame。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:10:32