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

求助:如何将DataFrame的列名与值拆分到行和列结构?

解决DataFrame宽表转长表的思路与实现

你要完成的是宽格式(wide format)DataFrame到长格式(long format)的转换,这类操作在Pandas里有成熟的工具可以实现,下面我会一步步拆解思路,再给出具体代码示例:

核心逻辑梳理

你的原始表列名是nameX_attrY的固定格式,目标是把这些列拆成三个维度:ID(保留原有主键)、name(提取列名里的X数字)、attr1/attr2(提取列名里的Y对应的数值)。核心就是拆分列名中的结构化信息,再把分散的列值重新映射到新的行结构里。

具体实现步骤(以Pandas为例)

先假设你的原始DataFrame叫df,先处理好示例数据,再一步步转换:

1. 构造示例原始数据

先把你给出的示例转成可操作的DataFrame:

import pandas as pd

data = {
    'ID': [1, 1, 4, 5],
    'name1_attr1': [2, 3, 2, None],
    'name1_attr2': [3, 4, 4, None],
    'name2_attr1': [1, 3, 6, None],
    'name2_attr2': [2, 3, 7, None]
}
df = pd.DataFrame(data)

2. 用melt把宽表转成基础长表

先把除了ID之外的所有列转成「键-值」对的形式,方便后续拆分:

# 保留ID作为主键,把其他列转成name_attr(键)和value(值)
melted_df = df.melt(id_vars='ID', var_name='name_attr', value_name='value')

这一步后,你会得到一个包含ID、name_attr(比如name1_attr1)、value的长表。

3. 拆分name_attr列,提取name和attr编号

用字符串拆分和正则提取,把name_attr里的数字拆出来:

# 按下划线拆分列名,得到name和attr的原始字符串
melted_df[['name', 'attr']] = melted_df['name_attr'].str.split('_', expand=True)
# 提取name里的数字(比如name1转成1),并转成整数类型
melted_df['name'] = melted_df['name'].str.extract('(\d+)').astype(int)

4. 用pivot重塑成目标结构

把attr转成列,对应的值填充进去,再整理格式:

# 以ID和name为索引,把attr作为列,value作为对应值
final_df = melted_df.pivot_table(
    index=['ID', 'name'],
    columns='attr',
    values='value',
    aggfunc='first'  # 保证每个组合只取第一个值,避免重复
).reset_index()

# 重命名列,和目标结构对齐
final_df.columns = ['ID', 'name', 'attr1', 'attr2']
# 过滤掉全空的无效行(比如ID=5的那些)
final_df = final_df.dropna(subset=['attr1', 'attr2']).reset_index(drop=True)

5. 简化方案:用wide_to_long一步到位

Pandas专门提供了wide_to_long工具处理这种带编号的列名,代码更简洁:

# 先把列名转成多级索引,拆分name和attr
df.columns = pd.MultiIndex.from_tuples(
    [('ID', '')] + [tuple(col.split('_')) for col in df.columns if col != 'ID']
)
# 堆叠多级索引,直接得到长表
final_df = df.stack(0).reset_index()
final_df.rename(columns={'level_1': 'name', 0: 'attr1', 1: 'attr2'}, inplace=True)
# 提取name的数字并过滤空值
final_df['name'] = final_df['name'].str.extract('(\d+)').astype(int)
final_df = final_df.dropna(subset=['attr1', 'attr2']).reset_index(drop=True)

关键注意事项

  • 缺失值处理:原始数据里ID=5的行全是空值,转换后记得用dropna过滤掉这些无效行
  • 列名格式兼容:如果你的实际列名格式有变化(比如不是nameX_attrY),要调整正则表达式确保正确提取编号
  • 数据类型:提取的name编号要转成整数,避免字符串类型影响后续排序或计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:51:38