Pandasdrill

Grouping and aggregation Updated November 2026

value_counts

df["col"].value_counts() returns how many times each distinct value appears, sorted from most to least frequent. normalize=True gives shares instead of counts and dropna=False includes a row for missing values.

Syntax

Series.value_counts(normalize=False, sort=True, ascending=False, bins=None, dropna=True)
PartWhat it is
normalizeTrue returns proportions that sum to 1
sort / ascendingSort by count (default, largest first)
binsFor numeric data, count into this many equal-width intervals
dropnaFalse adds a count for NaN

Examples

import pandas as pd
import numpy as np

df = pd.DataFrame({"plan": ["free", "pro", "free", "team", "free", np.nan]})
df["plan"].value_counts()

Result: plan free 3 pro 1 team 1 Name: count, dtype: int64

df["plan"].value_counts(normalize=True).round(2)

Result: plan free 0.6 pro 0.2 team 0.2 Name: proportion, dtype: float64

Shares are computed over the five non-missing values.

df["plan"].value_counts(dropna=False)

Result: plan free 3 pro 1 team 1 NaN 1 Name: count, dtype: int64

Common mistakes

  • The result is a Series, not a DataFrame: call .reset_index() to get columns named plan and count.
  • Missing values are excluded by default, so proportions may not reflect the full table; pass dropna=False.
  • Counts split across variants like "Free" and "free ": normalize text with str.strip().str.lower() first.

Practice value_counts

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

  • Shares with value_countsReturn the share of orders for each product as a fraction between 0 and 1, largest share first.
  • Count rows per groupReturn the number of orders each rep has, as a Series indexed by rep in alphabetical order.

Questions

How do I sort value_counts by value instead of count?

Append .sort_index(): df["col"].value_counts().sort_index().

How do I get value counts as a DataFrame with a percentage column?

counts = s.value_counts(); pd.DataFrame({"count": counts, "pct": (counts / counts.sum() * 100).round(1)}).

value_counts or groupby size?

They give the same numbers. value_counts is shorter for one column and sorts by frequency; groupby().size() is better when you group by several columns or want the keys sorted.

Related

  • 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.
  • unique and nuniqueHow to get distinct values in pandas with unique, count them with nunique, count distinct per group with groupby, handle NaN, and see counts for all columns.
  • 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.
  • 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.

Previous: str.splitNext: pd.crosstab