Reshaping Data with stack()
and unstack()
in Pandas
1. Introduction
While melt()
and pivot
reshape DataFrames between wide and long formats, Pandas also provides stack()
and unstack()
for reshaping MultiIndex DataFrames.
stack()
→ compresses a level of column labels into rows.unstack()
→ expands a level of row index into columns.
These operations are extremely useful when working with hierarchical indices in Pandas.
2. Example Dataset
import pandas as pd
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Math': [85, 90, 95],
'Science': [88, 92, 96],
'English': [80, 85, 89]
}
df = pd.DataFrame(data)
df = df.set_index('Name') # Make Name the index
print(df)
Output:
Math Science English
Name
Alice 85 88 80
Bob 90 92 85
Charlie 95 96 89
3. Using stack()
stacked = df.stack()
print(stacked)
Output:
Name
Alice Math 85
Science 88
English 80
Bob Math 90
Science 92
English 85
Charlie Math 95
Science 96
English 89
dtype: int64
👉 Notice how the columns collapsed into a row index, creating a MultiIndex Series.
4. Using unstack()
unstacked = stacked.unstack()
print(unstacked)
Output:
English Math Science
Name
Alice 80 85 88
Bob 85 90 92
Charlie 89 95 96
👉 The unstack()
reversed the effect of stack()
.
5. Controlling Levels in MultiIndex
Let’s extend our dataset by creating a hierarchical index:
data = {
'Class': ['A', 'A', 'B', 'B'],
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Math': [85, 90, 88, 76],
'Science': [88, 92, 84, 80]
}
df = pd.DataFrame(data)
df = df.set_index(['Class', 'Name'])
print(df)
Output:
Math Science
Class Name
A Alice 85 88
Bob 90 92
B Charlie 88 84
David 76 80
Stack the columns
stacked = df.stack()
print(stacked)
Output:
Class Name
A Alice Math 85
Science 88
Bob Math 90
Science 92
B Charlie Math 88
Science 84
David Math 76
Science 80
dtype: int64
Unstack at different levels
unstacked = stacked.unstack(level=-1) # Last level
print(unstacked)
Output:
English Math Science
Class Name
A Alice NaN 85 88
Bob NaN 90 92
B Charlie NaN 88 84
David NaN 76 80
6. Summary
stack()
→ turns columns into rows.unstack()
→ turns row index into columns.- Works best with MultiIndex DataFrames.
- Useful for reshaping data in hierarchical structures.
Yes — the Seaborn datasets are great for demonstrating stack()
and unstack()
. Let me show you using e.g. the Titanic and Tips datasets. I’ll write example code + explain what happens.
🔍 Examples with Seaborn’s Titanic & Tips
import pandas as pd
import seaborn as sns
# Load Titanic
titanic = sns.load_dataset('titanic')
print(titanic.head(5))
Example 1: Titanic — unstack after grouping
# Group Titanic by Pclass and Survived, count numbers
grouped = titanic.groupby(['pclass', 'survived']).size()
print(grouped.head())
# Unstack survived so that survived values become columns
unstacked = grouped.unstack()
print(unstacked)
- Here,
grouped
is a Series with MultiIndex (levels: pclass, survived). unstack()
converts one level of the row index (survived) to columns.- Result: rows = pclass, columns = survived (0,1).
- Useful to see how many survived vs not in each passenger class.
Example 2: Titanic — stack back
stacked_back = unstacked.stack()
print(stacked_back)
- This takes the unstacked DataFrame and turns the “survived” column level back into a row-level index.
- You essentially get back the
grouped
Series (with MultiIndex).
Example 3: Using Tips dataset with pivot, then stack/unstack
tips = sns.load_dataset('tips')
print(tips.head(5))
Suppose you want counts of “day” vs “sex”:
counts = tips.groupby(['day', 'sex']).size().unstack()
print(counts)
- Rows: days (Thur, Fri, Sat, Sun)
- Columns: sexes (Male, Female) with counts
Then stack:
stacked_counts = counts.stack()
print(stacked_counts)
- This moves the sex column level back into the index, giving back a Series with MultiIndex (day, sex).
✅ Why these are useful
unstack()
is good for turning a groupby result into a “cross-tab” or pivot-table–like layout, where one categorical variable becomes columns.stack()
is the inverse, helpful when you need a tidy long format (e.g. for plotting, or further processing).- With Titanic & Tips datasets, there are many categorical columns, so stacking/unstacking helps you reshape.