Pandas pd.melt() Function
pd.melt()is a top-level function of the Pandas library, used toconvert wide table to long tableIt "melts" wide-format data containing multiple columns into long format, similar to the unpivot operation in Excel.
This is one of the most commonly used functions in data reshaping, especially useful when data needs to be converted to long format before data visualization, or when multiple columns need to be combined into one column.
Word Definition: meltIt means "to melt, to fuse"; here it refers to "melting" the wide table structure into a long table structure, similar to gathering multiple columns of data together.
Basic Syntax and Parameters
pd.melt()is a top-level function of the Pandas library, used to convert wide-format data to long format.
Syntax Format
pd.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)
Parameter Description
- Parameter:
frame- Type: DataFrame.
- Description:Required parameter. The source data DataFrame, i.e., the data to be converted from wide to long.
- Parameter:
id_vars- Type: column name, tuple list, or None.
- Description: Columns used as identifier (ID) variables, these columns remain unchanged after conversion. Can be a single column name or a list of column names. If not specified, all columns will be treated as value_vars.
- Parameter:
value_vars- Type: column name, tuple list, or None.
- Description: The columns to be "melted", i.e., which columns are converted into rows. If not specified, all columns except id_vars will be converted.
- Parameter:
var_name- Type: string or None.
- Description: The new column name generated to store the original column names. Default is 'variable'.
- Parameter:
value_name- Type: string.
- Description: The generated value column name. Default is 'value'.
- Parameter:
col_level- Type: int, str, or None.
- Description: If the columns are MultiIndex, specify the level to melt.
Function Description
- Return value: Returns a DataFrame, with data converted from wide format to long format.
- Effect: Melts the values of multiple columns into two columns: one column stores the original column names (variable), and one column stores the corresponding values (value).
Examples
Let us thoroughly master, through a series of examples from simple to complex,pd.melt()the usage of.
Example 1: Basic Usage - Convert a Simple Wide Table to a Long Table
Examples
# 1. Create wide-format data (one column for each quarter)
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'Q1_sales': [100, 150, 200],
'Q2_sales': [120, 160, 210],
'Q3_sales': [130, 170, 220]
})
print("=== Original Wide Format Data ===")
print(df)
# 2. Use pd.melt() to convert to long format
melted = pd.melt(df, id_vars=['name'], value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales'])
print("\n=== pd.melt() converted to long format ===")
print(melted)
# 3. Custom column names
melted_custom = pd.melt(
df,
id_vars=['name'],
value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales'],
var_name='quarter',
value_name='sales'
)
print("\n=== Custom column names ===")
print(melted_custom)
Expected output:
=== 原始宽格式数据 ===
name Q1_sales Q2_sales Q3_sales
0 Alice 100 120 130
1 Bob 150 160 170
2 Charlie 200 210 220
=== pd.melt() 转换为长格式 ===
name variable value
0 Alice Q1_sales 100
1 Bob Q1_sales 150
2 Charlie Q1_sales 200
3 Alice Q2_sales 120
4 Bob Q2_sales 160
5 Charlie Q2_sales 210
6 Alice Q3_sales 130
7 Bob Q3_sales 170
8 Charlie Q3_sales 220
=== 自定义列名 ===
name quarter sales
0 Alice Q1_sales 100
1 Bob Q1_sales 150
2 Charlie Q1_sales 200
3 Alice Q2_sales 200
Code analysis:
- The original data is in wide format, each row is a person, and Q1, Q2, Q3 are sales data columns for three quarters.
id_vars=['name']Specify the name column to remain unchanged as the identifier.value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales']Specify the columns to be melted.- The result adds a variable column (storing original column names) and a value column (storing corresponding values).
- Using
var_nameandvalue_namecan customize the names of the new columns.
Example 2: Without Specifying value_vars - Melt All Columns Except id_vars
When value_vars is not specified, all columns except id_vars are automatically melted.
Examples
# 1. Create data with more columns
df = pd.DataFrame({
'id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'],
'math': [90, 85, 92],
'english': [88, 90, 87],
'science': [95, 88, 91]
})
print("=== Original Data ===")
print(df)
# 2. Only specify id_vars, automatically melt all other columns
melted = pd.melt(df, id_vars=['id', 'name'])
print("\n=== Melt all non-id columns ===")
print(melted)
# 3. Case with multiple id_vars
print("\n=== Multiple id_vars ===")
melted_multi = pd.melt(df, id_vars=['name'], value_vars=['math', 'english', 'science'])
print(melted_multi)
# 4. Use only one id_vars
print("\n=== One id_vars ===")
melted_one = pd.melt(df, id_vars=['id'])
print(melted_one)
Expected output:
=== 原始数据 === id name math english science 0 1 Alice 90 88 95 1 2 Bob 85 90 88 2 3 Charlie 92 87 91 === 融化所有非id列 === id name variable value 0 1 Alice math 90 1 2 Bob math 85 2 3 Charlie math 92 3 1 Alice english 88 4 2 融化为两列(variable 和 value)。 - 不指定 value_vars 时,系统会自动识别并熔化除 id_vars 外的所有列 - id_vars 可以是单个列或多个列的组合
Code analysis:
- When not specified,
value_varsit will automatically meltid_varsall columns except id_vars. - When only id_vars is specified and value_vars is not, each data row produces as many new rows as there are value_vars.
- This method is very convenient when you need to process multi-column data uniformly.
Example 3: No id_vars - Melt All Columns
When id_vars is not specified, the original data's index serves as the identifier.
Examples
# 1. Create data (without an explicit id column)
df = pd.DataFrame({
'Q1': [100, 150, 200],
'Q2': [120, 160, 210],
'Q3': [130, 170, 220]
})
print("=== Original Data ===")
print(df)
# 2. Do not specify id_vars, use the default index
melted = pd.melt(df)
print("\n=== Without specifying id_vars ===")
print(melted)
# 3. Restore the original index
print("\n=== Reset index ===")
melted_with_index = pd.melt(df, ignore_index=False)
print(melted_with_index)
# 4. Practical case: create an identifier
df_with_id = pd.DataFrame({
'year': [2023, 2023, 2023],
'Q1': [100, 150, 200],
'Q2': [120, 160, 210]
})
print("\n=== Original data (with year) ===")
print(df_with_id)
# First add year to id_vars
melted_year = pd.melt(df_with_id, id_vars=['year'])
print("\n=== Melt result including year ===")
print(melted_year)
Expected output:
=== 原始数据 ===
Q1 Q2 Q3
0 100 120 130
1 150 160 170
2 200 210 220
=== 不指定 id_vars ===
variable value
0 Q1 100
1 Q1 150
2 融化所有列,将原始列名转为 variable 列的值,原始值转为 value 列。
Code analysis:
- When id_vars is not specified, only the variable and value columns remain.
- Using
ignore_index=Falsecan preserve the original index, making it easy to compare with the original data later. - In practice, one or more id_vars are usually specified to retain key information.
Example 4: Practical Case - Preparation for Data Visualization
melt() is a great helper for data visualization; many plotting libraries (such as Seaborn, Matplotlib) are better at handling long-format data.
Examples
# 1. Create sales data (one column per region)
sales = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'Jan': [1200, 1500, 900, 1100],
'Feb': [1350, 1600, 950, 1200],
'Mar': [1100, 1450, 880, 1050]
})
print("=== Wide-format sales data ===")
print(sales)
# 2. Melt into long format (for visualization)
sales_long = pd.melt(
sales,
id_vars=['product'],
var_name='month',
value_name='sales'
)
print("\n=== Long-format sales data ===")
print(sales_long)
# 3. Data processing example: calculate year-over-year growth
# Add month number
month_map = {'Jan': 1, 'Feb': 2, 'Mar': 3}
sales_long['month_num'] = sales_long['month'].map(month_map)
print("\n=== Add month number ===")
print(sales_long)
# 4. Filter data for a specific month
feb_sales = sales_long[sales_long['month'] == 'Feb']
print("\n=== Sales data for February ===")
print(feb_sales)
Expected output:
=== 宽格式销售数据 === product Jan Feb Mar 0 A 1200 1350 1100 product Jan 180 170 6 === 长格式销售数据(用于可视化) === product month sales 0 A Jan 1200 1 B Jan 1500 2 C Jan 900 3 D Jan 1100 4 A Feb 1350
Code analysis:
- Wide-format data has one column per region/time point, making it easy to view and enter data.
- Long-format data has one row per observation, which is the standard format for statistical analysis.
- Visualization libraries such as Seaborn accept long-format data, making it easy to create grouped bar charts, line charts, etc.
- Using
id_varscan keep categorical variables such as product and region from being melted.
Example 5: Melting with Multi-level Column Index
When a DataFrame has a multi-level column index, you can usecol_levelthe parameter.
Examples
# 1. Create data with a multi-level column index
df = pd.DataFrame(
[[100, 110, 200, 210], [150, 160, 180, 190]],
index=['Store_A', 'Store_B'],
columns=pd.MultiIndex.from_tuples([
('Electronics', 'Q1'), ('Electronics', 'Q2'),
('Furniture', 'Q1'), ('Furniture', 'Q2')
], names=['Category', 'Quarter'])
)
print("=== Original data (multi-level column index) ===")
print(df)
# 2. Melt all columns (without specifying a level)
print("\n=== Melt all columns ===")
melted_all = pd.melt(df, ignore_index=False)
print(melted_all)
# 3. Melt only the inner level (Quarter)
print("\n=== Melt only the Quarter level ===")
melted_quarter = pd.melt(df, col_level=1)
print(melted_quarter)
# 4. Melt the outer level (Category)
print(n=== Only melt the Category level ===)
melted_category = pd.melt(df, col_level=0)
print(melted_category)
Expected output:
=== 原始数据(多层列索引)=== Category Electronics Furniture Quarter Q1 Q2 Q1 融化不同层级会产生不同的结果: - 融化内层(Quarter)保留 Category 作为 id - 融化外层(Category)保留 Quarter 作为 id
Code explanation:
- For a DataFrame with a multi-level column index, column names are in tuple form: (Category, Quarter).
col_level=0Melt the outer level (Category), keep Quarter as id.col_level=1Melt the inner level (Quarter), keep Category as id.- This flexibility allows you to choose which level to melt based on your analysis needs.
Other extensionsTip:
pd.melt()It is a great helper for data visualization. Most plotting libraries (e.g., Seaborn, Plotnine) are better at handling long-format data; using melt() to transform data before plotting is a common practice.
Pandas Common Functions