Pandas df.stack() Function
df.stack()is a member method of DataFrame, used toconvert column indexes to row indexes. It "stacks" the columns of wide-format data into rows, producing a Series or DataFrame with a hierarchical index.
This is an important operation for data reshaping, usually used together withunstack()to achieve mutual conversion of data.
Word Definition: stackIt means "to stack, to pile up"; here it refers to "stacking" column data into rows, converting a wide table into a long table.
Basic Syntax and Parameters
df.stack()is an instance method of DataFrame, called via the dot operator.
Syntax Format
DataFrame.stack(level=-1, dropna=True)
Parameter Description
- Parameter:
level- Type: int, str, list of int, or list of str.
- Description: Specifies the level to stack. For multi-level indexes, you can specify a specific level number (starting from 0) or a level name. The default is -1, which means the innermost level.
- Parameter:
dropna- Type: Boolean.
- Description: Whether to drop rows that are all NaN in the result. The default is True, which removes rows where all values are NaN.
Function Description
- Return Value: Returns a Series or DataFrame. If only one column of the original DataFrame is stacked, a Series is returned; otherwise, a DataFrame is returned.
- Effect: Converts column indexes to row indexes, producing a longer data format. The stacked data is in "long format", which is convenient for statistical analysis or visualization.
Examples
Let us, through a series of examples from simple to complex, thoroughly masterdf.stack()its usage.
Example 1: Basic Usage - Converting Columns to Rows
Example
import numpy as np
# 1. Create wide-format data (one column per quarter)
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'Q1': [100, 150, 200],
'Q2': [120, 160, 210],
'Q3': [130, 170, 220]
})
print("=== Original wide-format data ===")
print(df)
print(f"Column names: {df.columns.tolist()}")
# 2. Use df.stack() to convert columns to rows
stacked = df.stack()
print("n=== df.stack() result ===")
print(stacked)
print(f"nType: {type(stacked)}")
# 3. Convert the result to a DataFrame for inspection
print("n=== Converted to DataFrame ===")
stacked_df = stacked.reset_index()
stacked_df.columns = ['name', 'quarter', 'sales']
print(stacked_df)
Expected output:
=== 原始宽格式数据 ===
name Q1 Q2 Q3
0 Alice 100 120 130
1 Bob 150 160 170
2 Charlie 'Q2', 'Q3'], columns=['name', 'quarter', 'sales']
...
Code explanation:
- The original data is in wide format, with Q1, Q2, Q3 as three columns of quarterly data.
stack()The three columns Q1, Q2, Q3 are "stacked" into rows.- The result is of type Series, with two levels of index: the outer level is the original row index, and the inner level is the original column names (quarters).
- After stacking, the data becomes "long format", with each row containing only one quarterly value.
Example 2: Stacking Multi-level Column Indexes
When a DataFrame has a multi-level column index, you can specify which level to stack.
Example
import numpy as np
# 1. Create data with a multi-level column index
# Outer level: product type (Electronics, Furniture)
# Inner level: quarter (Q1, Q2)
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=['Product', 'Quarter'])
)
print("=== Original data (multi-level column index) ===")
print(df)
print(f"Column index levels: {df.columns.names}")
# 2. Stack the inner column level (default, level=-1)
print("n=== Stack inner column level (level=-1) ===")
stacked_inner = df.stack()
print(stacked_inner)
# 3. Stack the outer column level
print("n=== Stack outer column level (level=0) ===")
stacked_outer = df.stack(level=0)
print(stacked_outer)
# 4. Stack all columns (produces a longer format)
print("n=== Stack all columns ===")
stacked_all = df.stack(level=[0, 1])
print(stacked_all)
Expected output:
=== 原始数据(多层列索引)=== Product Electronics Furniture Quarter Q1 Q2 Q1 Q ...
Code explanation:
- For a DataFrame with a multi-level column index, the column names are tuples: (Product, Quarter).
level=-1Stack the innermost level (default), i.e., the Quarter level, and the result keeps Product as columns.level=0Stack the outer level, i.e., the Product level, and the result keeps Quarter as columns.- This flexibility allows you to choose the level to stack according to your analysis needs.
Example 3: Handling Missing Values
Use thedropnaparameter to control how missing values are handled.
Example
import numpy as np
# 1. Create data containing missing values
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'Math': [100, np.nan],
'English': [90, 85],
'Science': [np.nan, 95]
})
print("=== Original data (containing missing values) ===")
print(df)
# 2. dropna=True (default), drop rows that are all NaN
print("n=== dropna=True (default) ===")
stacked_drop = df.stack(dropna=True)
print(stacked_drop)
# 3. dropna=False, keep NaN values
print("n=== dropna=False ===")
stacked_keep = df.stack(dropna=False)
print(stacked_keep)
# 4. Practical application: organize the stacked result into an analyzable long format
print("n=== Organized into a long-format DataFrame ===")
result = df.set_index('name').stack().reset_index()
result.columns = ['name', 'subject', 'score']
print(result)
# 5. Drop missing values
result_clean = result.dropna()
print("n=== After dropping missing values ===")
print(result_clean)
Expected output:
=== 原始数据(包含缺失值)===
name Math English Science
0 Alice 100.0 90.0 NaN
1 Bob NaN 85.0 95.0
2=== 堆叠内层列 (level=-1) ===
Store_A Electronics Q1 100
Q2 110
Furniture Q1 200
Q2 210
Store_B Electronics Q1 150
...
Code explanation:
dropna=True(Default) drops rows where all values are NaN.- In data analysis, it is usually necessary to keep the original data, and then drop missing values as needed.
- After stacking, use
reset_index()to convert the hierarchical index into ordinary columns for easier subsequent processing.
Example 4: Combined Use of stack and unstack
stack()andunstack()They are inverse operations; using them together enables flexible reshaping of data.
Example
# 1. Create initial data
df = pd.DataFrame({
'product': ['A', 'B', 'C'],
'North': [100, 150, 200],
'South': [180, 170, 160],
'East': [190, 200, 210]
})
print("=== Original data ===")
print(df)
# 2. Use unstack to convert regions to columns (first convert to a multi-level index)
df_indexed = df.set_index('product')
print("n=== After setting the index ===")
print(df_indexed)
# 3. Use stack to convert columns to rows (stack is the inverse of unstack)
print("n=== unstack + stack round trip ===")
# First unstack
unstacked = df_indexed.unstack()
print("unstack result:")
print(unstacked)
# Then stack back
restacked = unstacked.stack()
print("nstack back:")
print(restacked)
# 4. Complete example: create a multi-level index and then convert
print("n=== Multi-level index conversion ===")
# Create a DataFrame with a multi-level index
multi_df = pd.DataFrame(
[[100, 110], [150, 160]],
index=pd.MultiIndex.from_tuples([('A', '2023'), ('B', '2023')], names=['product', 'year']),
columns=['North', 'South']
)
print("Original multi-level index data:")
print(multi_df)
# unstack year
print("nunstack year:")
print(multi_df.unstack(level='year'))
# unstack columns
print("nunstack columns (convert to columns):")
print(multi_df.unstack(level='columns'))
Expected output:
=== unstack + stack 往返 ===
unstack 结果:
product
North A 100
B 150
C 200
South A 180
B 170
...
Code explanation:
stack()Converts column indexes to row indexes, changing a wide table into a long table.unstack()Converts row indexes to column indexes, changing a long table into a wide table.- Using the two together can achieve arbitrary reshaping of data.
- For data analysis, it is very important to understand the inverse relationship between these two operations.
Other ExtensionsTip:
stack()andunstack()is a core tool for data reshaping.stack()stacks columns into rows (wide to long),unstack()splits rows into columns (long to wide).
Pandas Common Functions