np.unique: Distinct Values & Counts
Find the distinct values of an array (always sorted), count how often each appears, and locate first occurrences with return_counts, return_index and return_inverse.
"Which teams have won the IPL in the last ten seasons, and how many titles each?" That is two questions — the distinct values, and their frequencies. np.unique answers both in one call. It is NumPy's version of Python's set() plus collections.Counter, and the NumPy cousin of Pandas value_counts().
Definition
np.unique(a)returns the sorted distinct values of an array — each value appears exactly once. With optional flags it also returns how many times each value occurs (return_counts), the index of its first occurrence (return_index), and an array that maps every original element to its position in the unique array (return_inverse).
- Sorted — the result is always in ascending order, not in order of appearance.
- Distinct — duplicates removed.
- Flattened by default — a 2D input gives a 1D result unless you pass
axis. - Multiple return values — when you set any flag to
True,np.uniquereturns a tuple that you unpack.
Syntax
python
np.unique(ar, return_index=False, return_inverse=False,
return_counts=False, axis=None, *, equal_nan=True)| Parameter | Meaning | Default |
|---|---|---|
ar | input array | required |
return_index | also return the index of the first occurrence of each unique value | False |
return_inverse | also return indices that rebuild the original from the unique array | False |
return_counts | also return how many times each unique value appears | False |
axis | find unique rows (axis=0) / columns instead of single values; None = flatten | None |
equal_nan | treat all NaNs as one value | True |
Return order when several flags are set: unique, index, inverse, counts.
Example — distinct winners
python
import numpy as np
winners = np.array(["CSK", "MI", "CSK", "KKR", "MI", "GT", "CSK", "MI", "KKR", "CSK"])
print(np.unique(winners))
print(len(np.unique(winners)))text
['CSK' 'GT' 'KKR' 'MI']
4How it works: 10 entries, 4 different teams, returned in alphabetical (sorted) order.
Example — return_counts: titles per team
python
teams, counts = np.unique(winners, return_counts=True)
print(teams)
print(counts)
for t, c in zip(teams, counts):
print(t, c)
print(teams[counts.argmax()])text
['CSK' 'GT' 'KKR' 'MI']
[4 1 2 3]
CSK 4
GT 1
KKR 2
MI 3
CSKHow it works: counts[i] is the frequency of teams[i]. Combining with argmax finds the mode (most frequent value) — CSK with 4 titles.
Example — return_index and return_inverse
python
u, first = np.unique(winners, return_index=True)
print(u, first)
u, inv = np.unique(winners, return_inverse=True)
print(inv)
print(u[inv])text
['CSK' 'GT' 'KKR' 'MI'] [0 5 3 1]
[0 3 0 2 3 1 0 3 2 0]
['CSK' 'MI' 'CSK' 'KKR' 'MI' 'GT' 'CSK' 'MI' 'KKR' 'CSK']How it works:
return_index: CSK first won in season index 0, GT in 5, KKR in 3, MI in 1.return_inverse: each original entry replaced by its code inu(CSK=0, GT=1, KKR=2, MI=3).u[inv]rebuilds the original. This is label encoding — turning categories into integers for machine learning.
Example — numbers and 2D arrays
python
scores = np.array([4, 6, 1, 4, 0, 6, 4, 1]) # runs off each ball
v, c = np.unique(scores, return_counts=True)
print(v, c)
print(np.unique(np.array([[1, 2], [2, 3]])))
print(np.unique(np.array([[1, 2], [1, 2], [3, 4]]), axis=0))text
[0 1 4 6] [1 2 3 2]
[1 2 3]
[[1 2]
[3 4]]How it works: the over had one dot ball, two singles, three fours and two sixes. A 2D input is flattened by default; with axis=0 whole rows are compared, and the duplicate row [1 2] is removed.
Note: NumPy 2 also has
np.unique_values,np.unique_counts,np.unique_inverseandnp.unique_all(Array API style).np.unique_counts(winners)returns a result with.valuesand.countsfields — same numbers as above.
Comparison
| Task | Python | NumPy | Pandas |
|---|---|---|---|
| distinct values | set(lst) (unordered) | np.unique(a) (sorted) | s.unique() (order of appearance) |
| frequency of each | Counter(lst) | np.unique(a, return_counts=True) | s.value_counts() |
| number of distinct | len(set(lst)) | len(np.unique(a)) | s.nunique() |
Common mistakes
- ❌ Expecting values in order of first appearance. ✅
np.uniquealways sorts. To get appearance order:u[np.argsort(first)]usingreturn_index. - ❌
counts = np.unique(a, return_counts=True)and then usingcountsas the counts. ✅ It is a tuple — unpack:values, counts = .... - ❌ Forgetting a 2D array is flattened. ✅ Pass
axis=0for unique rows.
Interview tip
Q: How do you find the most frequent value in a NumPy array?
A: vals, counts = np.unique(a, return_counts=True) then vals[counts.argmax()]. For non-negative integers, np.bincount(a).argmax() is even faster.
Key points to remember
- np.unique returns the distinct values of an array, always sorted ascending.
- return_counts=True also returns how many times each unique value appears (like value_counts).
- return_index=True gives the index of each value's first occurrence; return_inverse=True maps every element to its unique-array position.
- With any flag set, the result is a tuple — unpack it: values, counts = np.unique(a, return_counts=True).
- The mode is values[counts.argmax()].
- A 2D array is flattened unless axis is given; axis=0 finds unique rows.
Try it yourself
Titles per team with return_counts
First occurrence and label encoding
Practice: analyse an over
Revision Flashcards
Tap a card to flip it and see the answer.
