Wide-format reporting
Convert long, hierarchical-index data into a wide table with one index level represented as columns.
Pandas · Module
Reshapes selected index levels into columns. MultiIndex inputs produce a DataFrame; a regular index produces a Series.
DataFrame.unstack reshapes one or more index levels into the innermost column level. With a MultiIndex it returns a DataFrame; with an ordinary index it returns a Series, and absent combinations can be populated through fill_value.
DataFrame.unstack(*level=-1*, *fill_value=None*, *sort=True*)| Name | Type | Description |
|---|---|---|
level | int, str, or list of these, default -1 | Index level number, name, or list of levels to move to the columns axis; defaults to the last level. |
fill_value | scalar | Value used to replace missing entries produced by unstacking. |
sort | bool, default True | Whether to sort the levels in the resulting MultiIndex columns. |
Series or DataFrame: with a MultiIndex, a DataFrame whose pivoted index labels become the innermost column labels; otherwise, a Series.
import pandas as pd
index = pd.MultiIndex.from_tuples(
[("East", "A"), ("East", "B"), ("West", "A")],
names=["region", "product"],
)
df = pd.DataFrame({"sales": [10, 20, 15]}, index=index)
wide = df.unstack(level="product", fill_value=0, sort=False)
print(wide)Moves the named product index level into columns, fills the missing West/B cell with zero, and preserves first-seen order.
Convert long, hierarchical-index data into a wide table with one index level represented as columns.
Create a matrix-like layout from categorical index levels for comparison or downstream calculations.
Control gaps and ordering while reshaping grouped or indexed measurements.
It pivots selected index levels onto the columns axis. For a MultiIndex, the result is a DataFrame whose innermost column level contains the pivoted labels.
Follow-up: What happens with a non-MultiIndex? It returns a Series, which is the analogous result when there is no hierarchical index to expand.
level identifies the index level or levels to move and accepts an integer, a level name, or a list of either. Its default is -1, meaning the last index level.
Follow-up: How would you select a level robustly when index order may change? Give the level a stable name and pass that name rather than relying on its numeric position.
fill_value supplies a replacement for missing values created by the reshape, while sort controls ordering of the resulting MultiIndex columns and defaults to True. Setting sort=False retains first-appearance ordering for the relevant result ordering.
Follow-up: When should fill_value be avoided? Avoid it when missingness carries meaning or when the replacement value would force an unsuitable interpretation of the data.
DataFrame.stackSeries.unstack