Passing a list or array of indices instead of a slice lets you select an arbitrary, non-contiguous, and even repeated or reordered set of elements — indexing with [3, 0, 3, 1] pulls out the elements at positions 3, 0, 3 again, and 1, in exactly that order, something a basic slice can't express. For a 2D array, passing two index arrays, one per dimension, selects specific (row, column) pairs element-wise, rather than a rectangular block — the two arrays are paired up positionally, not crossed together. Unlike basic slicing, fancy indexing always returns a new copy of the selected data.
1Understanding Fancy Indexing
Passing a list or array of indices instead of a slice lets you select an arbitrary, non-contiguous, and even repeated or reordered set of elements — indexing with [3, 0, 3, 1] pulls out the elements at positions 3, 0, 3 again, and 1, in exactly that order, something a basic slice can't express. For a 2D array, passing two index arrays, one per dimension, selects specific (row, column) pairs element-wise, rather than a rectangular block — the two arrays are paired up positionally, not crossed together. Unlike basic slicing, fancy indexing always returns a new copy of the selected data.
For 2D fancy indexing, passing two separate index arrays selects specific (row, column) pairs one at a time, not a rectangular sub-block — use np.ix_() instead when you actually want every combination of a set of rows with a set of columns.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[[0, 2, 4]])2Practical Example
Here is a real-world application of Fancy Indexing showing how it is used in production NumPy code.
import numpy as np
matrix = np.arange(12).reshape(3, 4)
print(matrix[[0, 1], [1, 3]])3Best Practices
Follow these guidelines when working with Fancy Indexing:
1. Use fancy indexing to select or reorder specific, non-contiguous elements, instead of building the result with a Python loop
2. Remember fancy indexing always returns a copy, unlike basic slicing, so modifying the result never affects the original array
3. Use np.ix_() when you want a rectangular selection of specific rows crossed with specific columns, rather than paired (row, column) coordinates
Tip: For 2D fancy indexing, passing two separate index arrays selects specific (row, column) pairs one at a time, not a rectangular sub-block — use np.ix_() instead when you actually want every combination of a set of rows with a set of columns.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[[0, 2, 4]])