Indexing, slicing and masks
A 2-D array is a table of numbers. One index pair picks a cell, a slice picks a row or a column, and a True/False mask picks every value that passes a test.
- Read a cell, a row and a column of a 2-D array with
[row, column]and: - Use a boolean mask from a comparison to keep matching values, also from a second array of the same length
- Explain why a slice is a view of the original and when to call
copy()
Readings from several stations over several days form a table: one row per station, one column per day. NumPy stores that as a 2-D array, and its shape is (rows, columns). Inside the brackets, a comma separates the position along each dimension: tmax[1, 0] is row 1, column 0. A colon on its own means *all of them*, so tmax[:, 4] is column 4 from every row, and tmax[0, 1:4] is part of row 0.
Run each example to see what it prints. Running examples doesn't count toward progress.
import numpy as np stations = ["Wichita", "Orlando", "Sioux Falls"] # Daily highs (C), 1 to 5 January 2024: one row per station, one column per day tmax = np.array([ [-0.5, 6.7, 9.4, 7.2, 1.7], [22.2, 17.8, 21.7, 18.3, 23.3], [1.1, 2.8, -1.0, -1.0, 1.1], ]) print(tmax.shape) print(stations[1], tmax[1, 0]) print(tmax[2]) print(tmax[:, 4]) print(tmax[0, 1:4])
import numpy as np tmax = np.array([[-0.5, 6.7], [22.2, 17.8], [1.1, 2.8]]) print(tmax[3, 0])
A comparison on an array compares every value and gives back an array of True/False, the same length. That mask goes inside the brackets: values[mask] keeps the values where the mask is True, in order. The mask can come from a different array of the same length, which is how you ask *on which dates was it below freezing?* Because True counts as 1, mask.sum() counts the matches.
import numpy as np dates = np.array(["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-06", "2024-01-07"]) tmax = np.array([1.1, 2.8, -1.0, -1.0, 1.1, -0.5, -4.9]) # Sioux Falls freezing = tmax < 0 print(freezing) print(dates[freezing]) print(freezing.sum(), "of", tmax.size, "days stayed below 0 C")
Views and copies. A slice such as tmax[:3] does not copy anything: it is a view, a window onto the same memory. Changing a value through the view changes the original, which is fast but surprising. A mask always builds a new array. When you want to change values without touching the original, call copy() first.
When to use it: a position when you know where the value is, a slice for a run of rows or columns, a mask when you know the rule but not the positions. Mistakes to avoid: forgetting the comma (tmax[1][0] works but tmax[1, 0] is the array way), editing a slice you meant to copy, and masking with an array of a different length.
a[row, col]picks a cell;:means every row or column; slices stop before their end.- A comparison makes a True/False mask;
values[mask]keeps the matches andmask.sum()counts them. - Slices are views of the original; masks build new arrays;
copy()makes a separate array to change. - Next: arithmetic between arrays of different shapes, and the rule that decides when it works.