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

如何使用Pandas将多年度宽格式DataFrame转换为长格式?

问题描述

现有如下结构的DataFrame:

{
    'year1_ID': ['Id1', 'Id2'], 
    'year1_Name':['Name1', 'Name2'], 
    'year1_Info': ['Info1','Info2'],
    'year1_AddInfo':['AddInfo1','AddInfo2'], 
    'year2_ID': ['Id3', 'Id4'], 
    'year2_Name':['Name3', 'Name4'], 
    'year2_Info': ['Info3','Info4'],
    'year2_AddInfo':['AddInfo3','AddInfo4'],
    'year3_ID': ['Id5', 'Id6'], 
    'year3_Name':['Name5', 'Name6'], 
    'year3_Info': ['Info5','Info6'],
    'year3_AddInfo':['AddInfo5','AddInfo6']
}

表格形式如下:

year1_ID  year1_Name year1_Info year1_AddInfo  year2_ID  year2_Name year2_Info year2_AddInfo  year3_ID  year3_Name year3_Info year3_AddInfo
Id1       Name1      Info1      AddInfo1       Id3       Name3      Info3      AddInfo3       Id5       Name5      Info5      AddInfo5
Id2       Name2      Info2      AddInfo2       Id4       Name4      Info4      AddInfo4       Id6       Name6      Info6      AddInfo6

其中ID、Name、Info、AddInfo是跨年度重复的属性,需要将其转换为如下长表格式:

Year   ID   Name   Info   AddInfo
year1  Id1  Name1  Info1  AddInfo1
year1  Id2  Name2  Info2  AddInfo2
year2  Id3  Name3  Info3  AddInfo3
year2  Id4  Name4  Info4  AddInfo4
year3  Id5  Name5  Info5  AddInfo5
year3  Id6  Name6  Info6  AddInfo6

尝试过pd.melt()和pd.stack()未得到预期结果,寻求正确实现方案。


解决方案

使用Pandas的pd.wide_to_long()方法可以直接处理这种带前缀的宽表转长表需求,这是专门为这类场景设计的工具,比melt或stack更简洁高效。

代码实现

import pandas as pd

# 构造示例DataFrame(替换为你的实际数据)
df = pd.DataFrame({
    'year1_ID': ['Id1', 'Id2'], 
    'year1_Name':['Name1', 'Name2'], 
    'year1_Info': ['Info1','Info2'],
    'year1_AddInfo':['AddInfo1','AddInfo2'], 
    'year2_ID': ['Id3', 'Id4'], 
    'year2_Name':['Name3', 'Name4'], 
    'year2_Info': ['Info3','Info4'],
    'year2_AddInfo':['AddInfo3','AddInfo4'],
    'year3_ID': ['Id5', 'Id6'], 
    'year3_Name':['Name5', 'Name6'], 
    'year3_Info': ['Info5','Info6'],
    'year3_AddInfo':['AddInfo5','AddInfo6']
})

# 执行宽表转长表
result = pd.wide_to_long(
    df,
    stubnames=['ID', 'Name', 'Info', 'AddInfo'],  # 指定重复的属性名
    i=df.index,  # 以原始行索引作为分组标识,确保每行数据对应转换
    j='Year',    # 提取出的年份列名
    sep='_',     # 列名中前缀与属性的分隔符
    suffix='.*'  # 匹配年份部分的正则,这里匹配任意字符
).reset_index(drop=True)

# 调整列顺序,让Year列排在首位
result = result[['Year', 'ID', 'Name', 'Info', 'AddInfo']]

print(result)

代码说明

  • stubnames:指定所有列中重复的属性名称(即去掉年份前缀后的部分)。
  • i:设置分组依据,这里用原始DataFrame的行索引,保证每一行的多年度数据能正确拆分。
  • j:定义提取出的年份列的名称。
  • sep:指定列名中年份与属性的分隔符(这里是下划线_)。
  • suffix:用正则匹配年份部分,.*表示匹配任意字符,适配不同格式的年份命名。

运行后即可得到目标格式的长表。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:54:17