Pandasdrill

Grouping and aggregation Updated November 2026

pivot_table

pd.pivot_table(df, index="row_key", columns="col_key", values="v", aggfunc="sum") builds an Excel-style summary table, aggregating duplicates with the chosen function (mean by default). fill_value replaces empty cells and margins=True adds row and column totals.

Syntax

pd.pivot_table(df, values=None, index=None, columns=None, aggfunc="mean", fill_value=None, margins=False)
PartWhat it is
indexColumn(s) that become the rows
columnsColumn(s) whose values become the column headers
valuesColumn(s) to aggregate
aggfunc"mean" (default), "sum", "count", a list, or a dict per value column
fill_valueValue used for combinations that have no data
marginsTrue adds an All row and column with totals

Examples

import pandas as pd

df = pd.DataFrame({"region": ["East", "East", "West", "West", "East"],
                   "product": ["A", "B", "A", "A", "A"],
                   "sales": [100, 150, 200, 50, 30]})
pd.pivot_table(df, index="region", columns="product", values="sales", aggfunc="sum")

Result: product A B region East 130.0 150.0 West 250.0 NaN

Both columns become float because the empty West/B cell is NaN.

pd.pivot_table(df, index="region", columns="product", values="sales",
               aggfunc="sum", fill_value=0, margins=True)

Result: product A B All region East 130 150 280 West 250 0 250 All 380 150 530

pd.pivot_table(df, index="region", values="sales", aggfunc=["sum", "count"])

Result: sum count sales sales region East 280 3 West 250 2

Common mistakes

  • Values look wrong because the default aggfunc is mean, not sum: pass aggfunc="sum" explicitly.
  • NaN cells where a combination has no rows: pass fill_value=0.
  • DataError or dropped columns when values is omitted: pivot_table aggregates every numeric column; name the values you want.

Practice pivot_table

These drills check your answer on live data, free, no account needed.

  • Pivot table with a fill valueBuild a table of total revenue with one row per region and one column per quarter. Combinations with no sales should show 0, not NaN.

Questions

What is the difference between pivot and pivot_table?

pivot reshapes without aggregating and fails on duplicate index/column pairs. pivot_table aggregates duplicates (mean by default), so it works on raw transaction data.

How do I flatten a pivot table back to normal columns?

Call .reset_index() and, if the columns are a MultiIndex, join them: pt.columns = ["_".join(map(str, c)).strip("_") for c in pt.columns].

How do I pivot with percentages?

Divide by the totals: pt.div(pt.sum(axis=1), axis=0) gives row percentages; pt / pt.sum() gives column percentages.

Related

  • pivotHow df.pivot works in pandas: turn a long table with key and value columns into a wide table, what index, columns and values mean, and the duplicates error.
  • groupbyHow groupby works in pandas: group by one or more columns, apply sum, mean, count or size, get a flat table with as_index=False, and iterate over groups.
  • pd.crosstabHow to build a contingency table in pandas with pd.crosstab: counts of one column against another, totals with margins, row or column percentages, sums.
  • meltHow to use melt in pandas to turn wide data (one column per month or category) into long format with a variable and a value column, keeping id columns.

Previous: aggNext: merge