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

pandas DataFrame melt操作方法及常见使用场景解决方案

Pandas DataFrame melt 操作通用指南

在pandas相关的提问中,经常能看到用户咨询DataFrame的melt操作问题,但现有问题大多过于特定或缺少通用说明,本文将明确说明以下三点核心内容:

  • melt是什么?
  • 如何使用melt?
  • 什么时候需要使用melt?

核心概念说明

  • melt是什么:melt是pandas提供的宽表转长表的操作,也叫“反透视”操作,可以将指定的多列数据转为行,同时保留固定列的数值,实现表结构的行列转换。
  • 如何使用melt:核心调用格式为pd.melt(df, id_vars=None, value_vars=None, var_name=None, value_name='value'),各参数作用如下:
    • id_vars:指定转换过程中保持不变的列
    • value_vars:指定需要转为行的列,默认会使用所有未被指定为id_vars的列
    • var_name:指定存储原列名的新列的列名
    • value_name:指定存储原列值的新列的列名
  • 什么时候需要使用melt:当你需要将多个同类型的列转为行,方便后续分组统计、可视化、或者适配其他数据处理逻辑时,就可以使用melt操作。

演示数据集

本次演示使用随机生成的学生年龄、各科成绩数据集,结构如下:

import pandas as pd

df = pd.DataFrame({
    'Name': ['Bob', 'John', 'Foo', 'Bar', 'Alex', 'Tom'],
    'Math': ['A+', 'B', 'A', 'F', 'D', 'C'],
    'English': ['C', 'B', 'B', 'A+', 'F', 'A'],
    'Age': [13, 16, 16, 15, 15, 13]
})

输出的原始表结构:

Name Math English  Age
0   Bob   A+       C   13
1  John    B       B   16
2   Foo    A       B   16
3   Bar    F      A+   15
4  Alex    D       F   15
5   Tom    C       A   13

常见问题解答

问题1:将科目列转为行,保留学生姓名、年龄,同时对应展示科目和对应成绩

需求:把Math、English两个科目列转为行,保留Name、Age两列不变,新增Subject列存储科目名,Grade列存储对应成绩。
实现代码:

res = df.melt(
    id_vars=['Name', 'Age'],
    var_name='Subject',
    value_name='Grade'
)

问题2:仅保留Math科目的melt操作

需求:和问题1逻辑一致,但仅转换Math列,过滤掉English列的数据。
实现代码:

res = df.melt(
    id_vars=['Name', 'Age'],
    value_vars=['Math'],
    var_name='Subject',
    value_name='Grades'
)

说明:通过value_vars参数指定仅需要转为行的列,其他未指定的非id列会被自动过滤。


问题3:melt后按成绩分组,拼接对应学生姓名和科目

需求:melt转换后按成绩分组,将同成绩对应的学生姓名、对应科目分别按顺序用逗号拼接。
实现代码:

# 先执行melt转换,提取姓名、科目、成绩三列
melted = df.melt(id_vars=['Name'], value_vars=['Math', 'English'], var_name='Subject')
# 按成绩分组后拼接字符串
res = melted.groupby('value', as_index=False).agg(
    Name=('Name', ','.join),
    Subjects=('Subject', ','.join)
).sort_values('value')

问题4:melt长表逆操作还原为原始宽表

需求:已知melt后的长表由代码df = df.melt(id_vars=['Name', 'Age'], var_name='Subject', value_name='Grades')生成,需要将其还原为初始的宽表结构。
实现代码:

# 先构造题目给定的melt长表
melted = df.melt(id_vars=['Name', 'Age'], var_name='Subject', value_name='Grades')
# 使用pivot方法还原宽表
res = melted.pivot(index=['Name', 'Age'], columns='Subject', values='Grades').reset_index().rename_axis(columns=None)

问题5:按学生姓名分组,拼接每个学生的科目和成绩为字符串

需求:melt转换后按学生姓名分组,将每个学生的所有科目、对应成绩分别用逗号拼接为字符串。
实现代码:

# 先执行melt转换
melted = df.melt(id_vars=['Name', 'Age'], var_name='Subject', value_name='Grades')
# 按姓名分组拼接
res = melted.groupby('Name', as_index=False).agg(
    Subject=('Subject', ','.join),
    Grades=('Grades', ','.join)
).sort_values('Name')

问题6:全量melt,输出仅包含列名和对应值两列的结构

需求:将DataFrame所有列都转为值,最终输出仅包含原列名、原列值两列的结构。
实现代码:

res = df.melt(var_name='Column', value_name='Value')

说明:不指定id_vars参数时,所有列都会被转为行,最终生成两列分别存储原列名和原列值。


内容的提问来源于stack exchange,提问作者U13-Forward

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:39:01