Pandasdrill

Grouping and aggregation Updated November 2026

unique and nunique

df["col"].unique() returns an array of the distinct values in order of appearance and df["col"].nunique() returns how many there are, excluding NaN by default. df.nunique() gives the count for every column, and groupby("k")["col"].nunique() counts distinct values per group.

Syntax

Series.unique()   |   Series.nunique(dropna=True)   |   df.nunique(axis=0, dropna=True)
PartWhat it is
dropnanunique: False counts NaN as a value

Examples

import pandas as pd

df = pd.DataFrame({"cust": ["a", "b", "a", "c", None],
                   "region": ["N", "N", "S", "S", "S"]})
df["cust"].unique()

Result: array(['a', 'b', 'c', None], dtype=object)

unique keeps None/NaN as a value.

df["cust"].nunique()

Result: 3

df.groupby("region")["cust"].nunique()

Result: region N 2 S 2 Name: cust, dtype: int64

South has a and c; the missing customer is not counted.

Common mistakes

  • unique() returns a numpy array, not a list or Series: wrap with list() or use drop_duplicates() for a Series.
  • nunique and len(unique()) differ by one: unique includes NaN, nunique excludes it unless dropna=False.
  • Counting distinct across two columns with nunique only counts each column separately; use df[["a", "b"]].drop_duplicates().shape[0] for distinct pairs.

Practice unique and nunique

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

  • Count rows per groupReturn the number of orders each rep has, as a Series indexed by rep in alphabetical order.
  • Remove duplicate recordsThe `leads` table has repeated emails. Keep only the most recent row for each email, which is the last one in the table. Keep the original row labels.

Questions

How do I get unique values sorted?

sorted(df["col"].dropna().unique()) or df["col"].drop_duplicates().sort_values().

How do I count distinct values with their frequencies?

value_counts() lists each distinct value with how often it occurs.

How do I list unique values of all columns?

{c: df[c].unique() for c in df.columns} builds a dict; df.nunique() gives just the counts.

Related

  • 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.
  • drop_duplicatesHow to remove duplicates in pandas with drop_duplicates: whole rows or a subset of columns, keep first, last or none, and finding duplicates with duplicated.
  • 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.
  • describeWhat df.describe returns in pandas: count, mean, std, min, quartiles and max for numeric columns, including text columns, custom percentiles and transposing.

Previous: to_csv and to_excelNext: where, mask and np.where