How do I count how often each value appears in a column?
Short answer
Use value_counts on the column for a quick frequency table sorted by count. Pass normalize for proportions, and dropna to include missing values.
The short version
Call value_counts() on the column. It returns each distinct value with how many times it appears, sorted from most to least common. Add normalize=True for proportions instead of raw counts, and dropna=False if you want missing values counted too.
A worked example
import pandas as pd
df = pd.DataFrame({"colour": ["red", "blue", "red", "red", "blue"]})
print(df["colour"].value_counts())
colour
red 3
blue 2
Name: count, dtype: int64
Proportions instead of counts
df["colour"].value_counts(normalize=True)
colour
red 0.6
blue 0.4
Name: proportion, dtype: float64
This is the quick way to answer "what share of rows are red" without dividing by the total yourself.
Counting missing values too
By default value_counts ignores NaN. If a missing value is itself worth counting, include it.
df["colour"].value_counts(dropna=False)
value_counts versus groupby
value_counts is a shortcut for the common case of counting one column. When you need to count within groups, or count and aggregate at the same time, groupby is the general tool.
# same idea, spelled with groupby
df.groupby("colour").size()
The difference is that value_counts sorts by frequency, while groupby().size() keeps the group order. Use value_counts for a fast look, and groupby when the count is one part of a larger summary.
Counting combinations
To count pairs, pass a list of columns to value_counts on the whole frame (pandas 1.1 and later).
df.value_counts(["colour"]) # extend the list for more columns
This gives frequencies for each combination of the listed columns, which is handy for spotting how two categories co-occur.