Q&A library Python

What are argsort and searchsorted in NumPy for?

Python Advanced argsortnumpysearchsorted

Short answer

argsort returns the positions that would sort an array, which lets you reorder several arrays consistently. searchsorted finds where a value would be inserted in a sorted array, which is a fast way to bucket values.

The short version

argsort returns the indices that would sort an array, rather than the sorted values. That lets you apply one array's ordering to another. searchsorted finds where a value would slot into a sorted array, which is a fast way to assign values to bins or to look them up.

argsort returns positions

import numpy as np

a = np.array([10, 30, 20])

a.argsort()        # array([0, 2, 1]) , the positions in sorted order
a[a.argsort()]     # array([10, 20, 30]) , the sorted values

The first element of the result, 0, says "the smallest value is at position 0". The second, 2, says "the next smallest is at position 2".

Why that indirection is useful

Because the positions can be applied to another array, keeping two parallel arrays in step.

names = np.array(["b", "a", "c"])
scores = np.array([2, 1, 3])

order = scores.argsort()
names[order]     # array(['a', 'b', 'c']) , names sorted by their score

You have sorted the names by the scores without ever sorting the names themselves. This is what a DataFrame's sort_values does under the hood, and it is why argsort exists.

searchsorted finds an insertion point

np.searchsorted([1, 3, 5], 4)   # 2

The value 4 would be inserted at position 2 to keep the array sorted (between 3 and 5). The array must already be sorted, or the answer is meaningless.

Why that is fast

searchsorted uses binary search, so it finds the position in a number of steps proportional to the logarithm of the size, rather than scanning. On a large sorted array this is dramatically faster than a linear search, and it handles a whole array of query values at once.

bins = np.array([0, 10, 20, 30])
values = np.array([5, 15, 25])
np.searchsorted(bins, values)    # which bin each value falls into

This is a fast, vectorised way to bucket values, and it is essentially what pd.cut does internally.

The side argument

By default, a value equal to a boundary goes to the left of it. Pass side="right" to change that, which controls whether a value sitting exactly on a bin edge falls into the lower or upper bin. As with cut, that boundary decision is a real choice and worth making deliberately.

When you would use these directly

Most of the time, sort_values and cut in pandas do what you need and are clearer. Reach for argsort and searchsorted when you are working in NumPy directly, when you need to apply one array's ordering to several others, or when you need the speed of a binary search inside a tight numeric routine. Knowing they exist also explains how the higher-level tools work, which helps when their behaviour surprises you.

Enjoying these?

Go from piecing together answers to real fluency.

Our courses take you from looking things up to doing the work with confidence, step by step on real data.

Browse the courses