Chapter 2 · Part 1

Indexing & slicing

Making arrays is only useful if you can reach into them. NumPy's indexing starts like Python lists and then adds two things that make it magic: 2-D indexing and boolean masks.

Single elements and slices

Indexing is zero-based, and slices are start:stop (stop excluded), optionally with a step:

slicing.py
v = np.array([10, 20, 30, 40, 50])

v[0]        # 10   — first element
v[-1]       # 50   — last element
v[1:4]      # [20 30 40]   — a slice
v[::-1]     # [50 40 30 20 10]   — reversed with a step of -1

Rows and columns

For a 2-D array you give two indices, [row, column] — and a : means "all of them", which is how you grab a whole row or column:

grid.py
a = np.array([[1, 2, 3],
            [4, 5, 6]])

a[1, 2]     # 6          — row 1, column 2
a[0]        # [1 2 3]    — the whole first row
a[:, 0]     # [1 4]      — the whole first column

Boolean masks — the superpower

Compare an array to a value and you get an array of True/False. Use that to pull out — or change — exactly the elements you want. No loop required:

masks.py
v = np.array([10, 20, 30, 40, 50])

v > 25          # [False False  True  True  True]
v[v > 25]       # [30 40 50]   — keep only elements matching the condition

Masks work for assignment too — write to the masked elements to change them in place:

v[v > 25] = 0
print(v)   # [10 20  0  0  0]
🎯 Your turn
Given the array below, replace every negative number with 0, leaving the rest unchanged. x = np.array([3, -1, 4, -5, 9, -2])

You can read and write any slice of an array. Now let's do math on all of it at once.