Python NumPy: How to Get the Indices of a Sorted Array Using NumPy
When sorting data, you often need to know where each element would end up after sorting - not just the sorted values themselves. NumPy's np.argsort() function returns the indices that would sort an array, which is essential for tasks like ranking, reordering related data, and finding the positions of the smallest or largest elements.
In this guide, we'll explain how argsort() works and show practical use cases.
Quick Answer
import numpy as np
arr = np.array([30, 10, 50, 20, 40])
sorted_indices = np.argsort(arr)
print(sorted_indices)
Output:
[1 3 0 4 2]
This means: the smallest element is at index 1 (value 10), the next smallest is at index 3 (value 20), and so on.
How np.argsort() Works
np.argsort() returns an array of indices that tells you the order in which elements should be arranged to sort the array:
import numpy as np
arr = np.array([30, 10, 50, 20, 40])
indices = np.argsort(arr)
print(f"Original: {arr}")
print(f"Sorted indices: {indices}")
print(f"Sorted values: {arr[indices]}") # Use indices to get sorted array
Output:
Original: [30 10 50 20 40]
Sorted indices: [1 3 0 4 2]
Sorted values: [10 20 30 40 50]
The key insight: arr[np.argsort(arr)] gives you the sorted array.
Syntax
numpy.argsort(a, axis=-1, kind=None, order=None)
| Parameter | Description | Default |
|---|---|---|
a | Input array | Required |
axis | Axis along which to sort | -1 (last axis) |
kind | Sorting algorithm: 'quicksort', 'mergesort', 'heapsort', 'stable' | 'quicksort' |
order | Field to sort by (for structured arrays) | None |
Returns: An array of indices with the same shape as the input.
Sorting in Descending Order
np.argsort() sorts in ascending order by default. To get descending order, reverse the result:
import numpy as np
arr = np.array([30, 10, 50, 20, 40])
# Ascending order indices
asc = np.argsort(arr)
print(f"Ascending: {asc} → {arr[asc]}")
# Descending order indices
desc = np.argsort(arr)[::-1]
print(f"Descending: {desc} → {arr[desc]}")
Output:
Ascending: [1 3 0 4 2] → [10 20 30 40 50]
Descending: [2 4 0 3 1] → [50 40 30 20 10]
Alternatively, negate the array before sorting:
desc = np.argsort(-arr)
print(f"Descending: {desc} → {arr[desc]}")
Sorting 2D Arrays
Along Columns (axis=0)
Sorts each column independently and returns the row indices that sort each column:
import numpy as np
arr = np.array([
[3, 1, 2],
[1, 3, 1],
[2, 2, 3]
])
indices = np.argsort(arr, axis=0)
print("Sorted indices along axis=0 (columns):")
print(indices)
Output:
Sorted indices along axis=0 (columns):
[[1 0 1]
[2 2 0]
[0 1 2]]
For the first column [3, 1, 2]: smallest is at row 1 (value 1), then row 2 (value 2), then row 0 (value 3).
Along Rows (axis=1)
Sorts each row independently and returns the column indices that sort each row:
import numpy as np
arr = np.array([
[3, 1, 2],
[1, 3, 1],
[2, 2, 3]
])
indices = np.argsort(arr, axis=1)
print("Sorted indices along axis=1 (rows):")
print(indices)
Output:
Sorted indices along axis=1 (rows):
[[1 2 0]
[0 2 1]
[0 1 2]]
For the first row [3, 1, 2]: smallest is at column 1 (value 1), then column 2 (value 2), then column 0 (value 3).
Practical Use Cases
Finding the Top N Elements
Get the indices of the 3 largest elements:
import numpy as np
scores = np.array([85, 92, 78, 95, 88, 73, 91])
names = np.array(['Alice', 'Bob', 'Carol', 'Dave', 'Eve', 'Frank', 'Grace'])
# Indices of top 3 scores
top3_indices = np.argsort(scores)[-3:][::-1]
print("Top 3 scorers:")
for i in top3_indices:
print(f" {names[i]}: {scores[i]}")
Output:
Top 3 scorers:
Dave: 95
Bob: 92
Grace: 91
Ranking Elements
Convert sorted indices into ranks:
import numpy as np
scores = np.array([85, 92, 78, 95, 88])
# Get ranks (1-based, where 1 = highest)
ranks = np.empty_like(scores)
sorted_indices = np.argsort(scores)[::-1] # Descending
ranks[sorted_indices] = np.arange(1, len(scores) + 1)
print(f"Scores: {scores}")
print(f"Ranks: {ranks}")
Output:
Scores: [85 92 78 95 88]
Ranks: [4 2 5 1 3]
Sorting Related Arrays Together
Sort multiple arrays based on the order of one:
import numpy as np
names = np.array(['Charlie', 'Alice', 'Bob', 'Dave'])
ages = np.array([30, 25, 28, 22])
# Sort both arrays by age
order = np.argsort(ages)
print("Sorted by age:")
for name, age in zip(names[order], ages[order]):
print(f" {name}: {age}")
Output:
Sorted by age:
Dave: 22
Alice: 25
Bob: 28
Charlie: 30
Sorting Strings
import numpy as np
words = np.array(['banana', 'apple', 'cherry', 'date'])
sorted_indices = np.argsort(words)
print(f"Original: {words}")
print(f"Sorted: {words[sorted_indices]}")
Output:
Original: ['banana' 'apple' 'cherry' 'date']
Sorted: ['apple' 'banana' 'cherry' 'date']
Choosing a Sorting Algorithm
| Algorithm | kind= | Stable? | Best For |
|---|---|---|---|
| Quicksort | 'quicksort' | ❌ | General use (default, fastest average) |
| Mergesort | 'mergesort' | ✅ | When stability matters |
| Heapsort | 'heapsort' | ❌ | Memory-constrained scenarios |
| Stable | 'stable' | ✅ | Alias for mergesort/timsort |
Stable sorting preserves the relative order of equal elements:
import numpy as np
arr = np.array([3, 1, 2, 1, 3])
unstable = np.argsort(arr, kind='quicksort')
stable = np.argsort(arr, kind='stable')
print(f"Quicksort: {unstable}")
print(f"Stable: {stable}")
Output:
Quicksort: [1 3 2 0 4]
Stable: [1 3 2 0 4]
argsort() vs sort() vs sorted()
| Function | Returns | Modifies Original |
|---|---|---|
np.argsort(arr) | Array of indices | ❌ |
np.sort(arr) | Sorted copy of the array | ❌ |
arr.sort() | None (sorts in place) | ✅ |
import numpy as np
arr = np.array([30, 10, 50])
print(f"argsort: {np.argsort(arr)}") # [1 0 2] (indices)
print(f"sort: {np.sort(arr)}") # [10 30 50] (sorted values)
Output:
argsort: [1 0 2]
sort: [10 30 50]
Conclusion
np.argsort() returns the indices that would sort an array, making it invaluable when you need to track original positions, sort related data together, find top/bottom N elements, or compute rankings.
For descending order, reverse the result with [::-1] or negate the array. It works on arrays of any dimension using the axis parameter and supports multiple sorting algorithms via the kind parameter.
Use 'stable' when the relative order of equal elements matters.