pd.crosstab
pd.crosstab(df["a"], df["b"]) counts how many rows have each combination of a and b, returning a table with a values as rows and b values as columns. normalize="index" turns counts into row percentages and margins=True adds totals.
Syntax
pd.crosstab(index, columns, values=None, aggfunc=None, margins=False, normalize=False)| Part | What it is |
|---|---|
index | Series (or list of Series) for the rows |
columns | Series (or list) for the columns |
values / aggfunc | Aggregate a third column instead of counting rows |
margins | True adds an All row and column |
normalize | True, "index" or "columns" to show proportions |
Examples
import pandas as pd
df = pd.DataFrame({"gender": ["F", "M", "F", "F", "M"],
"plan": ["free", "pro", "pro", "free", "free"],
"spend": [0, 20, 20, 0, 0]})
pd.crosstab(df["gender"], df["plan"])Result: plan free pro gender F 2 1 M 1 1
pd.crosstab(df["gender"], df["plan"], margins=True)Result: plan free pro All gender F 2 1 3 M 1 1 2 All 3 2 5
pd.crosstab(df["gender"], df["plan"], normalize="index").round(2)Result: plan free pro gender F 0.67 0.33 M 0.50 0.50
Each row sums to 1: the share of plans within each gender.
Common mistakes
- TypeError when passing column names as strings: crosstab takes Series, so write df["a"], not "a".
- NaN in the table after using values: pass aggfunc too, or fill with .fillna(0).
- Percentages look wrong: normalize=True divides by the grand total; use "index" for row shares or "columns" for column shares.
Practice pd.crosstab
These drills check your answer on live data, free, no account needed.
- Counts with crosstabCount the orders for each region (rows) and product (columns) with `pd.crosstab`.
Questions
crosstab or pivot_table?
crosstab is a shortcut for counting combinations of two or more columns and supports normalize directly. pivot_table is more general for aggregating a values column.
How do I cross-tabulate three variables?
Pass a list for index or columns: pd.crosstab([df.a, df.b], df.c) gives a two-level row index.
Related
- pivot_tableHow to build a pivot table in pandas with pivot_table: index, columns, values, aggfunc, fill_value for empty cells, margins for totals, several aggregations.
- value_countsHow to count values in a pandas column with value_counts: counts sorted by frequency, percentages with normalize=True, including NaN, and two-column combos.
- 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.
- cut and qcutHow to bin numeric data in pandas: pd.cut for fixed ranges with labels like age bands, pd.qcut for equal-sized quantile groups, right-closed edges and labels.