NUMPY:Indexing, slicing, and boolean masks

Mastering indexing, slicing, and boolean masks concepts and implementation.

Point, slice, then filter

Indexing an array uses the same square brackets as a list, with one extra rule: a comma separates axes. grid[0] is the first row. grid[0, 2] is the first row, third column.

import numpy as np

grid = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90],
])

print(grid[0, 2])
print(grid[:, 1])
print(grid[:2, :2])

Output:

30
[20 50 80]
[[10 20]
 [40 50]]

: means "every position on this axis". grid[:, 1] is the whole second column. Slices are views into the same data when the step is 1, so writing into a slice writes into grid.

A mask is an array of True and False

import numpy as np

temps = np.array([18.2, 21.5, 19.0, 27.4, 22.1])
hot = temps > 22
print(hot)
print(temps[hot])
print(temps[temps >= 20])

Output:

[False False False  True False]
[27.4]
[21.5 27.4 22.1]

temps > 22 does not return one boolean. It returns a boolean array of the same shape. Putting that array inside brackets keeps only the True positions.

Combine tests with & and |, and wrap each test in parentheses. Python's and and or do not work element by element.

import numpy as np

temps = np.array([18.2, 21.5, 19.0, 27.4, 22.1])
mild = (temps >= 19) & (temps <= 23)
print(temps[mild])

Output:

[21.5 19.  22.1]

What to notice

  • grid[1, 2] is one number. grid[1:2, 2] is an array of one number. The slice keeps the dimension.
  • A mask must match the axis you are filtering. temps[temps > 22] works because both sides have length 5.
  • (a > 0) & (a < 10) needs the parentheses. a > 0 & a < 10 is a different expression and usually an error.

Try this

From grid above, select the last column, then select only the values in that column that are greater than 50.

Next: doing arithmetic on whole arrays, including the broadcasting rule that lets a column and a row meet.