# 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)技术支持
# 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)技术支持
保留标识符列
使用 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()技术支持
# 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()技术支持
# 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()函数通过将一个或多个列转为行、同时保留选定的标识符列不变,来重塑 DataFrame。这使您的数据更易于筛选、分组、可视化与分析。在本教程中,我将向您演示如何使用
pandas.melt()函数,并比较它与pivot()、stack()和wide_to_long()等选项的差异。如果您刚开始学习 Python,我建议您参加 our Introduction to Python course,该课程涵盖数据类型、列表、基础函数和包等技能。如何使用 pandas.melt()
pandas.melt()通过将列名转换为新列中的取值,把 DataFrame 从宽格式转换为长格式。其语法如下:
其中:
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,保留原始索引。下面通过一个示例演示上述语法如何重塑数据。
假设您有如下数据集,每个产品的月度销量分别存放在不同的列中。
您可以使用
pandas.melt()将月份列转换为行。得到的 DataFrame 现在将每个月份作为单独的行存储。
常见的 pandas.melt() 示例
既然您已经理解了
pandas.melt()的语法,下面展示各参数单独使用时的行为。接下来的示例将使用上面的表格。仅熔化选定列
value_vars参数可指定要反透视的列。您可以只转换需要的列,而不是熔化每一个月份。在此示例中,仅熔化了一月和二月列。其余月份列将被忽略。
保留标识符列
使用
id_vars参数可在重塑其他列的同时,保留一个或多个列不变。在下面的示例中,“Product”和“Category”保持不变,而月度销量列被转换为行。
重命名输出列
您会注意到,输出列默认命名为
variable和value。使用var_name和value_name参数为它们赋予更具描述性的名称。例如,在下面的输出中,我们将变量列重命名为“Month”,将数值列重命名为“Sales”。
保留原始索引
默认情况下,
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_name与value_name,而非依赖默认的 variable 与 value 列名。在熔化后检查行数:尤其在熔化多列时,验证行数是否符合预期。
需要还原时使用 pivot():分析结束后若需恢复到原始宽格式,使用
pivot()函数。参加 our Writing Efficient Python Code 课程,了解如何编写高效、易调试与易维护的代码。
结语
pandas.melt()是将宽格式数据转换为长格式数据的标准 pandas 函数。一旦理解了id_vars与value_vars的作用,您就可以控制哪些列作为标识符保留、哪些列转换为行。若想系统学习 Python,您可以进一步学习我们的 Python Data Fundamentals 和 Python Programming Fundamentals 技能路径。