A group-by answers a question about one thing, like items sold per category. Sometimes you want two things at once: items per category, split by status. A pivot table lays that out as a grid: one row for each value of one column, one column for each value of another, and in each cell a summary of the rows that have both.
df.pivot_table(...) gives back that new table. You name four things: index, the column whose values become the rows; columns, the column whose values become the table's columns; values, the column that fills the cells; and aggfunc, how each cell combines its rows, like "sum" or "mean" (without it you get the mean). For example, the average spent per city, split by newsletter:
by_city = customers.pivot_table(
index="city",
columns="newsletter",
values="spent",
aggfunc="mean",
)
A pair with no rows at all gets NaN, "no value". fill_value=0 puts 0 in those cells instead. That's true for a sum (no lines means 0 items), but not for a mean, where an empty cell has no answer.
The starting code keeps the March 2026 lines of orders.csv in march: .str.startswith("2026-03") gives back True for each date that begins with 2026-03. Your program must print the items sold in March per category and status:
status cancelled paid category gifts 1 7 home 0 27 kitchen 0 24 office 0 44
Your task: build table from march with pivot_table: one row per category, one column per status, the sum of quantity in each cell and 0 in the empty cells, then print it with .to_string().
Assignment
Follow the Coding Tutorial to build the March table of items per category and status with pivot_table.
Hint
Write each argument on its own line, ending with a comma, between march.pivot_table( and the closing ). Without values, pandas tries to average every other column, and text can't be averaged.
Free plan: 30 tutor messages. PRO is unlimited.
