Fancy Indexing in NumPy

numpy
Published

March 11, 2024

Understanding Fancy Indexing

Fancy indexing uses arrays of indices to select elements from a NumPy array. This means you can select multiple, non-contiguous elements simultaneously. This contrasts with basic indexing which uses a single integer or a slice to access a contiguous sequence of elements.

Let’s illustrate with a simple example:

import numpy as np

arr = np.array([10, 20, 30, 40, 50])

print(arr[0])  # Output: 10
print(arr[1:3]) # Output: [20 30]

indices = np.array([0, 2, 4])
print(arr[indices])  # Output: [10 30 50]

indices = np.array([1, 3, 0])
print(arr[indices])  # Output: [20 40 10]

As you can see, fancy indexing allows us to select elements in any order, regardless of their position in the array. This flexibility is crucial for many data manipulation tasks.

Multi-Dimensional Fancy Indexing

The true power of fancy indexing shines when working with multi-dimensional arrays. You can use multiple arrays of indices to select elements along different axes.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

row_indices = np.array([0, 2])
col_indices = np.array([1, 2])

print(arr_2d[row_indices, col_indices])  # Output: [2 9]

This example selects elements at (0,1), (2,2) simultaneously.

Boolean Indexing: A Special Case of Fancy Indexing

Boolean indexing is a powerful variation of fancy indexing where you use a boolean array to select elements. Elements corresponding to True values in the boolean array are selected.

arr = np.array([1, 2, 3, 4, 5, 6])
bool_arr = np.array([True, False, True, False, True, False])

print(arr[bool_arr]) # Output: [1 3 5]

#Even better: Create the boolean array directly using a condition
print(arr[arr > 3]) # Output: [4 5 6]

Boolean indexing is extremely useful for filtering data based on certain conditions.

Advanced Techniques: Combining Indexing Methods

You can combine different indexing methods for more complex selections. For instance, you can use a combination of integer indexing, slicing, and fancy indexing.

arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr_2d[1:, [0,2]]) # Output: [[4 6] [7 9]]

This selects rows from index 1 onwards and columns 0 and 2.

Modifying Arrays with Fancy Indexing

Fancy indexing isn’t just for selecting elements; it’s also effective for modifying them.

arr = np.array([1, 2, 3, 4, 5])
indices = np.array([0, 2, 4])
arr[indices] = 100
print(arr) #Output: [100   2 100   4 100]

This example demonstrates how easily you can modify specific elements using fancy indexing. The flexibility and power of fancy indexing make it an indispensable tool for any serious NumPy user.