Reshaping and Pivot Tables
Reshaping changes representation, not the underlying observations. State the row grain—the meaning of one row—before and after the operation.
Choose the operation
| Need | Operation |
|---|---|
| Unique long-to-wide mapping | pivot |
| Long-to-wide with aggregation | pivot_table |
| Wide-to-long | melt or wide_to_long |
| Move index levels between axes | stack / unstack |
| Expand list-like cells to rows | explode |
| Cross-tabulate categories | crosstab |
wide = observations.pivot(index="date", columns="metric", values="value")
summary = observations.pivot_table(
index="region",
columns="product",
values="revenue",
aggfunc="sum",
fill_value=0,
margins=True,
)
pivot raises when more than one value exists for an index/column pair. That is
a useful grain check. Use pivot_table only when an aggregation is intentional,
and choose the aggregation explicitly.
Return to tidy form
long = wide.reset_index().melt(
id_vars="date",
var_name="metric",
value_name="value",
)
After reshaping, verify row counts or key uniqueness and distinguish structural
missing combinations from missing observed values. fill_value=0 is valid only
when “no represented observation” truly means zero.