Advanced NumPy Indexing
NumPy offers more indexing options than regular Python sequences.
In addition to the integer and slice indexing seen earlier, arrays can be indexed with integer arrays, boolean arrays, and fancy indexing.
Integer Array Indexing
The following example retrieves elements at positions (0,0), (1,1), and (2,0) in the array.
Example
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0, 1, 2], [0, 1, 0]]
print(y)
Output:
[1 4 5]
The following example retrieves the four corners of a 4x3 array. The row indices are [0,0] and [3,3], while the column indices are [0,2] and [0,2].
Example
import numpy as np
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print('Our array is:')
print(x)
print('\n')
rows = np.array([[0, 0], [3, 3]])
cols = np.array([[0, 2], [0, 2]])
y = x[rows, cols]
print('The four corner elements of this array are:')
print(y)
Output:
Our array is:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
The four corner elements of this array are:
[[ 0 2]
[ 9 11]]
The result returned is an ndarray object containing the corner elements.
You can combine slicing :
or …
with index arrays. Here's an example:
Example
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = a[1:3, 1:3]
c = a[1:3, [1, 2]]
d = a[..., 1:]
print(b)
print(c)
print(d)
Output:
[[5 6]
[8 9]]
[[5 6]
[8 9]]
[[2 3]
[5 6]
[8 9]]
Boolean Indexing
We can index the target array with a boolean array.
Boolean indexing retrieves elements from the array that meet specified conditions using boolean operations (e.g., comparison operators).
The following example retrieves elements greater than 5:
Example
import numpy as np
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print('Our array is:')
print(x)
print('\n')
# Now we will print elements greater than 5
print('Elements greater than 5 are:')
print(x[x > 5])
Output:
Our array is:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
Elements greater than 5 are:
[ 6 7 8 9 10 11]
The following example uses the ~
(complement operator) to filter out NaN values.
Example
import numpy as np
a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
print(a[~np.isnan(a)])
Output:
[1. 2. 3. 4. 5.]
The following example demonstrates how to filter out non-complex elements from an array.
Example
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print(a[np.iscomplex(a)])
Output:
[2.+6.j 3.5+5.j]
Fancy Indexing
Fancy indexing refers to indexing using integer arrays.
Fancy indexing uses the values of the index array as indices along a specified axis of the target array to retrieve values.
For a one-dimensional integer array index, if the target is a one-dimensional array, the result is the element at the corresponding position; if the target is a two-dimensional array, the result is the row at the corresponding index.
Unlike slicing, fancy indexing always copies the data into a new array.
One-dimensional Array
A one-dimensional array has only one axis, axis = 0, so it is indexed along this axis:
Example
import numpy as np
x = np.arange(9)
print(x)
# Read elements at specified indices in a one-dimensional array
print("-------Read elements at specified indices-------")
x2 = x[[0, 6]] # Using fancy indexing
print(x2)
print(x2[0])
print(x2[1])
Output:
[0 1 2 3 4 5 6 7 8]
-------Read elements at specified indices-------
[0 6]
0
6
### Reading Elements by Index
-------Reading Elements by Index-------
[0 6]
0
6
Two-dimensional Array
- Passing Sequential Index Array
Example
import numpy as np
x = np.arange(32).reshape((8, 4))
print(x)
# Reading specified rows by index
print("-------Reading Rows by Index-------")
print(x[[4, 2, 1, 7]])
print(x[[4, 2, 1, 7]])
outputs the rows corresponding to indices 4, 2, 1, 7, with the result being:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]
-------Reading Rows by Index-------
[[16 17 18 19]
[ 8 9 10 11]
[ 4 5 6 7]
[28 29 30 31]]
- Passing Reverse Index Array
Example
import numpy as np
x = np.arange(32).reshape((8, 4))
print(x[[-4, -2, -1, -7]])
The output is:
[[16 17 18 19]
[24 25 26 27]
[28 29 30 31]
[ 4 5 6 7]]
- Passing Multiple Index Arrays (Using np.ix_)
The np.ix_ function takes two arrays and generates a Cartesian product mapping.
The Cartesian product in mathematics is the product of two sets X and Y, denoted as X×Y, where the first object is a member of X and the second object is one of the possible ordered pairs from Y.
For example, A={a,b}, B={0,1,2}, then:
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
Example
import numpy as np
x = np.arange(32).reshape((8, 4))
print(x[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])])
The output is:
[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
```