跳至内容

pandas melt(): 将宽格式数据转换为长格式的最佳方式

学习如何使用 pandas.melt() 将 DataFrame 从宽格式重塑为长格式,并配合实用示例与常见用例。
更新 2026年8月4日  · 8分钟

用 AI 探索

在 ChatGPT 中打开在 Claude 中打开在 Perplexity 中打开

宽格式数据便于阅读,但许多分析和可视化任务在长格式下效果更佳。

pandas.melt() 函数通过将一个或多个列转为行、同时保留选定的标识符列不变,来重塑 DataFrame。这使您的数据更易于筛选、分组、可视化与分析。

在本教程中,我将向您演示如何使用 pandas.melt() 函数,并比较它与 pivot()stack()wide_to_long() 等选项的差异。如果您刚开始学习 Python,我建议您参加 our Introduction to Python course,该课程涵盖数据类型、列表、基础函数和包等技能。

如何使用 pandas.melt()

pandas.melt() 通过将列名转换为新列中的取值,把 DataFrame 从宽格式转换为长格式。

其语法如下:

pandas.melt(
    frame,
    id_vars=None,
    value_vars=None,
    var_name=None,
    value_name="value",
    col_level=None,
    ignore_index=True
)

其中:

  • frame:要重塑的 DataFrame。仅在使用 pandas.melt() 时必填。

  • id_vars:需要保持不变的列或列列表。这些列在重塑后用于标识每一行。

  • value_vars:要“反透视”(unpivot)的列或列列表。如果省略,pandas 会熔化所有不在 id_vars 中的列。

  • var_name:存储原始列名的新列名称。若未指定,默认为 “variable”

  • value_name:存储数值的新列名称。若未指定,默认为 “value”

  • col_level:可选,在处理多级列索引(MultiIndex)时指定要熔化的层级。

  • ignore_index:若为 True(默认),创建新的顺序索引;若为 False,保留原始索引。

下面通过一个示例演示上述语法如何重塑数据。

假设您有如下数据集,每个产品的月度销量分别存放在不同的列中。

宽格式 DataFrame 示例。

您可以使用 pandas.melt() 将月份列转换为行。

# Convert the DataFrame from wide format to long format
products_sales_2025_melted = products_sales_2025.melt(
    # Keep the Product and Category columns unchanged
    id_vars=["Product", "Category"],

    # Convert the month columns into rows
    value_vars=["January", "February", "March", "April", "May", "June"],

    # Name of the new column that stores the original column names
    var_name="Month",

    # Name of the new column that stores the corresponding sales values
    value_name="Sales"
)

# Display the reshaped DataFrame
products_sales_2025_melted.head(10)

得到的 DataFrame 现在将每个月份作为单独的行存储。

使用 pandas.melt() 转换为长格式的 DataFrame

常见的 pandas.melt() 示例

既然您已经理解了 pandas.melt() 的语法,下面展示各参数单独使用时的行为。接下来的示例将使用上面的表格。

仅熔化选定列

value_vars 参数可指定要反透视的列。您可以只转换需要的列,而不是熔化每一个月份。

在此示例中,仅熔化了一月和二月列。其余月份列将被忽略。

# Convert only the January and February columns into rows
product_sales_3month = products_sales_2025.melt(
    id_vars="Product",
    value_vars=["January", "February",]
)

product_sales_3month.head(20)

使用 pandas.melt() 熔化选定列

保留标识符列

使用 id_vars 参数可在重塑其他列的同时,保留一个或多个列不变。

在下面的示例中,“Product”和“Category”保持不变,而月度销量列被转换为行。

# Keep the Product and Category columns while melting the monthly sales
product_sales_cat = products_sales_2025.melt(
    id_vars=["Product", "Category"]
)

product_sales_cat.head()

使用 pandas.melt() 保留标识符列。

重命名输出列

您会注意到,输出列默认命名为 variablevalue。使用 var_namevalue_name 参数为它们赋予更具描述性的名称。

例如,在下面的输出中,我们将变量列重命名为“Month”,将数值列重命名为“Sales”。

# Keep the Product and Category columns while melting the monthly sales
# Rename Month and Sales columns
product_sales_cat = products_sales_2025.melt(
    id_vars=["Product", "Category"],
    var_name="Month",
    value_name="Sales"
)

product_sales_cat.head()

在 pandas.melt() 中使用 var_name 和 value_name 重命名输出列。

保留原始索引

默认情况下,pandas.melt() 会创建新的顺序索引。将 ignore_index=False 设置为保留原始行索引。

# Keep the original row index after reshaping
product_sales_index = products_sales_2025.melt(
    id_vars=["Product", "Category"],
    var_name="Month",
    value_name="Sales",
    ignore_index=False
)

product_sales_index.head(10)

在 pandas.melt() 中使用 ignore_index=False 保留原始索引。

在上面的示例中,原始行标签(0–5)会在每个月份重复,而不是被新的顺序索引替换。

何时应该使用 pandas.melt()?

pandas.melt() 适用于当数据为宽格式、需要转换为长格式以便分析或可视化的场景。我也常在以下用例中使用该函数:

  • 将宽格式数据转换为长格式:许多数据集把相关数值分散在多个列中。虽然这种格式易读,但会增加分析难度。pandas.melt() 能将这些列合并为单一列,同时保留标识符列,从而为后续处理创建更清晰的结构。

  • 为绘图做准备:许多绘图库(如 Seaborn)在创建图表时更偏好长格式数据。与其手动合并多列,不如使用 pandas.melt() 将数据重塑为这些库期望的格式。

  • 为统计分析做准备:当测量值集中在单一列而非分散在多列时,许多 pandas 操作(包括 groupby()、聚合、筛选和汇总统计)会更简单。使用 pandas.melt() 重塑数据,可减少针对不同变量编写的代码量。

  • 创建整洁数据集:整洁数据集要求每个变量存放在自己的列、每条观测占据自己的行。如果您的数据集中在多个列中包含重复测量,pandas.melt() 往往是将其转换为整洁格式的最快方式。

我建议您参加我们的 Introduction to Data Visualization with Seaborn 课程,学习如何在 Python 中创建并自定义多种图表,包括散点图、计数图、柱状图和箱线图。

pandas.melt() 与其他重塑函数的比较

Pandas 提供了多种数据重塑函数,各有用途。下面来比较它们之间的差异。

pandas.melt() vs. pivot()

下表展示了 pandas.melt()pivot() 函数的区别

melt()

pivot()

将宽数据转换为长数据。

将长数据转换为宽数据。

将列转换为行。

将行中的取值转换为列。

有助于为分析与可视化做准备。

有助于在报告中汇总或呈现数据。

因此,当测量值分散在多个列中时选择 melt();当您希望将行中的取值展开到各列时使用 pivot()

pandas.melt() vs. stack()

虽然二者都能重塑数据,但它们的差异如下

melt()

stack()

将常规列重塑为行。

将一个或多个列层级移入索引。

生成标准的 DataFrame。

生成带有多级索引(MultiIndex)的 Series 或 DataFrame。

对大多数分析任务而言更易读、易用。

更适合基于索引的重塑操作。

您 can 在需要处理分层索引或 MultiIndex 对象时使用 stack()

pandas.melt() vs. wide_to_long()

两者都将宽数据转换为长格式,but 它们面向的情形不同,如下所示。

melt()

wide_to_long()

灵活,几乎适用于任何 DataFrame。

为具有一致列命名模式的数据集而设计。

适合通用重塑。

适用于重复测量,如 Sales_2023、Sales_2024 和 Sales_2025。

如果您的数据集列名不规则,请使用 melt()。如果列遵循可预测的命名规范,请使用 wide_to_long() 以更少的代码完成重塑。

使用 pandas.melt() 的常见错误

尽管 pandas.melt() 使用起来相对直接,但我遇到过以下常见陷阱,以及对应的修正方法。

  • 忘记设置 id_vars:如果您未指定 id_vars,pandas 会将未列入 value_vars 的所有列视为数值列。这可能会把您原本想保留为标识符的列重塑掉。要修正这一点,请始终识别能唯一描述每条记录的列,并将它们传入 id_vars

  • 意外熔化了不该处理的列:如果省略 value_vars,pandas 会熔化所有未包含在 id_vars 中的列,这可能包含您并不打算重塑的列。因此,当您只想熔化部分列时,应始终显式指定 value_vars

  • 误解输出形状:熔化后,行数会增加,因为每个被选中的列会为每条记录生成一行。例如,一个有 10 行和 12 个月份列的 DataFrame,在熔化月份列后会产生 120 行。因此,请始终在重塑前后检查数据形状,确认熔化是否符合预期。

  • 混淆宽格式与长格式:务必记住,宽格式中,相似的取值分布在多个列中;而在长格式中,相似的取值集中在单一列中,另有一列用于标识变量。

使用 pandas.melt() 的最佳实践

为了让您的重塑代码更易理解与维护,使用 pandas.melt() 时我建议遵循以下最佳实践:

  • 先识别标识符列:确定哪些列应保持不变,然后将它们传入 id_vars

  • 重命名生成的列:使用 var_namevalue_name,而非依赖默认的 variable 与 value 列名。

  • 在熔化后检查行数:尤其在熔化多列时,验证行数是否符合预期。

  • 需要还原时使用 pivot():分析结束后若需恢复到原始宽格式,使用 pivot() 函数。

参加 our Writing Efficient Python Code 课程,了解如何编写高效、易调试与易维护的代码。

结语

pandas.melt() 是将宽格式数据转换为长格式数据的标准 pandas 函数。一旦理解了 id_varsvalue_vars 的作用,您就可以控制哪些列作为标识符保留、哪些列转换为行。

若想系统学习 Python,您可以进一步学习我们的 Python Data FundamentalsPython Programming Fundamentals 技能路径。

FAQs

我应该何时使用 pandas.melt()?

当您的数据将重复的取值分散在多个列中,而您希望获得用于分析或可视化的长格式 DataFrame 时使用它。

什么是 var_name 和 value_name?

这些参数用于重命名生成的列,分别存放原始列名及其对应的数值。

pandas.melt() 会修改原始 DataFrame 吗?

不会。它会返回一个新的重塑后的 DataFrame,原始数据保持不变。

melt() 与 pivot() 有何区别?

melt() 将宽格式数据转换为长格式,而 pivot() 则将长格式数据转换回宽格式。

melt() 与 stack() 有何区别?

melt() 在保留常规 DataFrame 的同时将列重塑为行;stack() 则将列移入索引,创建分层(MultiIndex)结构。

主题

与 DataCamp 一起学习 pandas

Courses

使用 pandas 高效导入数据

4小时
63.3K
学习从常见文件格式和系统中获取数据,如 CSV 文件、电子表格、JSON、SQL 数据库和 API。
查看详情Right Arrow
开始课程
查看更多Right Arrow