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

如何对DataFrame分组执行melt操作?现有代码生成冗余行求解决

问题分析与解决方法

问题背景

原始数据来自Excel,无法直接分享,构造的模拟DataFrame代码如下:

df = pd.DataFrame({0: ['id', 'id1', 'id', 'id2', 'id1', 'id', 'id3', 'id2'], 
                   1: ['col1', '1', 'col1', '4', '6', None, None, None], 
                   2: ['col2', '2', None, None, None, 'col2', None, '8'], 
                   3: ['col3', '3', 'col3', '5', '7', None, None, None]})

输出的原始DataFrame:

0     1     2     3
0   id  col1  col2  col3
1  id1     1     2     3
2   id  col1   NaN  col3
3  id2     4   NaN     5
4  id1     6   NaN     7
5   id   NaN  col2   NaN
6  id3   NaN   NaN   NaN
7  id2   NaN     8   NaN

期望将数据整理为如下格式:

id number variable value
id1      1     col1     1
id1      1     col2     2
id1      1     col3     3
id2      2     col1     4
id2      2     col2      
id2      2     col3     5
id1      2     col1     6
id1      2     col2      
id1      2     col3     7
id3      3     col1      
id3      3     col2      
id3      3     col3      
id2      3     col1      
id2      3     col2     8
id2      3     col3      

现有代码的问题

你编写的代码产生多余行的核心原因是:

  • 分组后每个子DataFrame包含了开头的id行(变量名定义行)和数据行,直接对整个子DF执行melt会把变量名行也转换成数据行,比如输出头部里的id行条目就是多余的
  • 未正确设置melt的var_name和value_name参数,导致列名不符合期望格式

解决方法

正确的处理逻辑是区分每个分组里的变量名行和数据行,步骤如下:

  1. 按id行分组后,提取每个分组的第一行作为该组的列名
  2. 取分组中剩余的行作为有效数据行,重置索引并应用新列名
  3. 对数据行执行melt,指定id_vars为id列,同时设置变量和值的列名
  4. 添加number编号,合并所有分组结果并调整列顺序

完整代码:

import pandas as pd

# 模拟DataFrame
df = pd.DataFrame({0: ['id', 'id1', 'id', 'id2', 'id1', 'id', 'id3', 'id2'], 
                   1: ['col1', '1', 'col1', '4', '6', None, None, None], 
                   2: ['col2', '2', None, None, None, 'col2', None, '8'], 
                   3: ['col3', '3', 'col3', '5', '7', None, None, None]})

# 按id行进行分组
groups = df.groupby(df[0].eq('id').cumsum())
final_dfs = []
number = 1

for _, group in groups:
    # 提取分组第一行作为列名
    var_names = group.iloc[0].values
    # 提取分组中除第一行外的数据行
    data = group.iloc[1:].reset_index(drop=True)
    # 为数据行设置列名
    data.columns = var_names
    # 执行melt转换,指定id列、变量列和值列的名称
    melted_data = data.melt(id_vars='id', var_name='variable', value_name='value')
    # 添加number编号
    melted_data['number'] = number
    final_dfs.append(melted_data)
    number += 1

# 合并所有分组结果
result = pd.concat(final_dfs, ignore_index=True)
# 调整列顺序以匹配期望输出
result = result[['id', 'number', 'variable', 'value']]
# 将NaN替换为空字符串(可选,根据需求调整)
result['value'] = result['value'].fillna('')

print(result)

执行后将得到与期望一致的输出。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:07:40