Skip to main content
v2026.11,858 entries · CC-BY 4.0

NumPy argsort: np.argsort() Syntax, Descending Order and Examples

How np.argsort returns sorting indices: axis, kind, descending order on any NumPy version, take_along_axis for 2-D, and multi-key sorting.

Written and maintained by CASRAI Editorial Board

Last updated

numpy.argsort() returns the indices that would sort an array, not the sorted values themselves. Those indices let you sort one array by another, pick the top-k records, or rank observations without moving the data. This guide covers the signature, descending order on every NumPy version, and how to apply the returned indices correctly in two or more dimensions.

What argsort is used for in research

Sorting values loses the link between each value and its original position. np.argsort keeps that link. Typical research uses, all of which follow directly from the definition (“returns the indices that would sort an array”):

  • Sort one array by another. If scores holds a measurement per sample and names holds the sample labels, names[np.argsort(scores)] lists the labels in score order.
  • Select the top-k or bottom-k records. Slice the index array instead of sorting the whole dataset again.
  • Rank observations. The positions in the index array order the data; for tie-aware ranks see the alternatives table below.

If your arrays contain missing values, read the companion guide on detecting, ignoring and replacing NaN in NumPy first, because sorting treats NaN in a fixed way (see Troubleshooting).

Install or access

NumPy is installed from the official install page at numpy.org/install. The two documented routes are:

  • pip: pip install numpy
  • conda: conda create -n my-env, then conda activate my-env, then conda install numpy

To keep a project isolated with a virtual environment, the same page lists python -m venv my-env, activation with source my-env/bin/activate (macOS and Linux) or my-env\Scripts\activate (Windows), and then pip install numpy. For a refresher on creating arrays, see creating a NumPy array from a list and reading its shape.

Step-by-step: using np.argsort

The signature

From the current NumPy reference:

numpy.argsort(a, axis=-1, kind=None, order=None, *, stable=None, descending=<no value>)
  • axis: the axis to sort along. The default is -1, the last axis. With axis=None the array is flattened first.
  • kind: one of 'quicksort' (the default), 'mergesort', 'heapsort' or 'stable'.
  • order: for arrays with named fields, the fields to compare first; unspecified fields break ties in dtype order.
  • stable: if True, equal values keep their original relative order. Added in NumPy 2.0.0.
  • descending: if True, the indices sort in descending order. Added in NumPy 2.5.0.

1. Sort a 1-D array

  1. Import NumPy and build an array: import numpy as np then x = np.array([3, 1, 2]).
  2. Call np.argsort(x). The documented result is array([1, 2, 0]): the smallest value sits at index 1, the next at index 2, the largest at index 0.
  3. Apply the indices with x[np.argsort(x)] to get the sorted values.

2. Sort along an axis of a 2-D array

With x = np.array([[0, 3], [2, 2]]) the reference shows:

  • np.argsort(x, axis=0) gives array([[0, 1], [1, 0]]) (sorts down each column).
  • np.argsort(x, axis=1) gives array([[0, 1], [0, 1]]) (sorts across each row).

3. Sort a flattened array and recover 2-D positions

Passing axis=None sorts the flattened array. To turn the flat indices back into row and column positions, use np.unravel_index:

ind = np.unravel_index(np.argsort(x, axis=None), x.shape)
# (array([0, 1, 1, 0]), array([0, 0, 1, 1]))
x[ind]
# array([0, 2, 2, 3])

4. Descending order, on any NumPy version

This is where most tutorials stop at one idiom, and the right choice depends on your NumPy version.

  • NumPy 2.5.0 or newer: np.argsort(x, descending=True). For x = np.array([3, 1, 2]) this gives indices [0, 2, 1]. The reference states that NaN values are placed at the end for both orders.
  • Older versions: the descending keyword does not exist. Reverse the ascending result with np.argsort(x)[::-1], which also gives [0, 2, 1] for the same array.

Reversing has a side effect on ties. Because the reversed list flips the order of equal values, their original relative order is lost. For numeric (signed) arrays, np.argsort(-x, kind='stable') keeps tied values in their original order while sorting descending. For x = np.array([1, 2, 1]) this returns [1, 0, 2], whereas np.argsort(x)[::-1] on the stable ascending order [0, 2, 1] returns [1, 2, 0]. Negating is not safe for unsigned integer types, so use the descending keyword there if your version has it.

5. Top-k and bottom-k

For the k largest values, slice the end of the ascending index array: np.argsort(x)[-2:] on [3, 1, 2] gives [2, 0], the positions of the values 2 and 3. For the k smallest, use np.argsort(x)[:k].

6. Sort by several keys with a structured array

For an array with named fields, order sets key priority. The reference example uses x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')]):

  • np.argsort(x, order=('x', 'y')) gives array([1, 0])
  • np.argsort(x, order=('y', 'x')) gives array([0, 1])

The same two keys in the opposite order produce opposite results, so the first name listed is the primary key.

Output and how to read it

The result is an integer array with the same shape as the input along the sorted axis. Reading it correctly depends on dimensions:

  • 1-D: a[index_array] returns the sorted array.
  • Any dimension: the reference gives the general rule as np.take_along_axis(a, index_array, axis=axis). For example, ind = np.argsort(x, axis=1) followed by np.take_along_axis(x, ind, axis=1) equals np.sort(x, axis=1).
  • Flattened (axis=None): use np.unravel_index as in step 3.

Writing x[np.argsort(x, axis=1)] on a 2-D array does not sort each row. It indexes whole rows by the values in the index array and returns a 3-D result, so use take_along_axis instead.

Choosing a sort algorithm (kind)

The NumPy sort reference lists these properties for the algorithms that kind selects:

kind Relative speed Worst case Work space Stable
quicksort 1 O(n^2) 0 No
heapsort 3 O(n*log(n)) 0 No
mergesort 2 O(n*log(n)) about n/2 Yes
timsort 2 O(n*log(n)) about n/2 Yes

The same page describes the default quicksort as an introsort that switches to heapsort when partitioning stalls, so its worst case in practice is O(n*log(n)). In argsort, 'stable' and 'mergesort' both use timsort under the covers, and 'mergesort' is kept for backwards compatibility. Choose a stable kind whenever tied values must keep their original order, for example when a second sort or a report depends on it.

Troubleshooting

NaN values appear at the end

Since NumPy 1.4.0, argsort works with real and complex arrays that contain NaN, and the NaN positions come last. The reference states this holds for descending order too, so a descending sort does not put NaN first.

Tied values come out in an unexpected order

The default quicksort is not stable. Pass kind='stable' (or stable=True on NumPy 2.0.0 or newer) to keep equal values in their original order.

2-D indexing gives the wrong shape

Use np.take_along_axis with the same axis, as described above.

The descending keyword is not recognised

That parameter was added in NumPy 2.5.0. Reverse the ascending result instead, as in step 4, or upgrade NumPy. Related array-shaping behaviour is covered in the guides on np.clip bounds and np.repeat axis and counts.

Free alternatives

All four are free, open-source tools documented on their official sites.

Tool What it returns Use it when Documented behaviour
numpy.sort The sorted values You do not need the original positions NaN values sort to the end (NumPy 1.4.0 and newer)
numpy.lexsort(keys, axis=-1) Indices from an indirect stable sort on several keys You have several separate arrays as keys The last key is the primary sort key; ties are broken by the second-to-last key, and so on
pandas.Series.sort_values A sorted Series Your data already lives in pandas Default ascending=True and na_position='last'; ascending=False sorts descending; mergesort and stable are the stable options
scipy.stats.rankdata Ranks, beginning at 1 You need ranks with defined tie handling rather than indices Tie method is one of average (default), min, max, dense, ordinal; nan_policy is propagate, omit or raise

For statistical modelling in Python after the sorting step, see ANOVA in Python with statsmodels.

FAQ

What does np.argsort return?

An integer array of indices that would sort the input. For np.array([3, 1, 2]) it returns array([1, 2, 0]).

How do I sort in descending order with np.argsort?

On NumPy 2.5.0 or newer, pass descending=True. On older versions, reverse the ascending result with [::-1], or use np.argsort(-x, kind='stable') for signed numeric data when ties must keep their original order.

How do I get the sorted array from the indices?

For 1-D input, a[index_array]. For any dimension, np.take_along_axis(a, index_array, axis=axis).

How do I sort a 2-D array by column or by row?

Use axis=0 to sort down columns and axis=1 to sort across rows, then apply the result with np.take_along_axis.

Is np.argsort stable?

Not by default. Use kind='stable', or stable=True on NumPy 2.0.0 and newer.

Where do NaN values go?

To the end of the result, in both ascending and descending order.

Sources

Date checked: 2026-10-29.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about NumPy argsort: np.argsort() Syntax, Descending Order and Examples

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.