Indexing 1D arrays
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10
print(arr[3]) # 40
print(arr[-1]) # 50Slicing 1D arrays
Slicing uses start:stop:step (stop is excluded).
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[1:4]) # [20 30 40]
print(arr[:3]) # [10 20 30]
print(arr[::2]) # [10 30 50]
print(arr[::-1]) # reverseIndexing 2D arrays (rows/columns)
McKinney's tip for reading 2D arrays: think of axis 0 as the "rows" and axis 1 as the "columns."
import numpy as np
mat = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print(mat[0, 0]) # 1
print(mat[1, 2]) # 6
print(mat[2, :]) # full row
print(mat[:, 1]) # full columnSub-arrays (2D slicing)
import numpy as np
mat = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
# rows 0..1 and cols 1..2
sub = mat[0:2, 1:3]
print(sub)Views vs copies (important)
Many slices are views (they share memory).
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
sub = arr[1:4] # view
sub[0] = 999
print(arr) # original changedTo force a copy:
sub = arr[1:4].copy()Boolean indexing (masking)
Boolean indexing is extremely useful for analytics filtering.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
mask = arr > 25
print(mask) # [False False True True True]
print(arr[mask]) # [30 40 50]Combine conditions
Use parentheses and & / | — the Python keywords and/or do not work with Boolean arrays.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[(arr >= 20) & (arr <= 40)])Fancy indexing
Select multiple specific indices using a list/array. Unlike slicing, fancy indexing always copies the data.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[[0, 2, 4]])flowchart LR A["ndarray"] --> B["Basic index
arr[2]"] A --> C["Slice
arr[1:4]"] A --> D["Boolean mask
arr[arr > 25]"] A --> E["Fancy index
arr[[0, 2, 4]]"] B --> F["Scalar or view"] C --> F D --> G["Copy"] E --> G
Check your understanding
For arr = np.array([10, 20, 30, 40, 50]), what is arr[1:4]?
Slices run from start up to but not including stop, so indices 1, 2 and 3 give [20 30 40].
Show answer
B — [20 30 40] — Slices run from start up to but not including stop, so indices 1, 2 and 3 give [20 30 40].
For the 3 by 3 matrix mat holding 1 through 9, what does mat[:, 1] return?
The first index selects rows (all of them) and the second selects column 1, which holds 2, 5 and 8.
Show answer
B — The full second column, 2 5 8 — The first index selects rows (all of them) and the second selects column 1, which holds 2, 5 and 8.
You run sub = arr[1:4] and then sub[0] = 999. What happens to arr?
Basic slices are views. Use arr[1:4].copy() to get an independent array.
Show answer
B — arr also changes, because the slice is a view sharing memory — Basic slices are views. Use arr[1:4].copy() to get an independent array.
Which expression selects values between 20 and 40 inclusive?
Boolean arrays need & or | with parentheses around each condition. The keywords and and or do not work element by element.
Show answer
B — arr[(arr >= 20) & (arr <= 40)] — Boolean arrays need & or | with parentheses around each condition. The keywords and and or do not work element by element.
Next
Continue to: Shape Manipulation & Reshape to learn how to change dimensions safely.
🧪 Try It Yourself
Exercise 1 – Slice a 2D Sub-array
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 2 – Filter with a Boolean Mask
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.Exercise 3 – A View Changes the Original
Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.
Press Run to see what your code prints.