Initialize standard arrays and advanced creation routines.
Generate pre-filled arrays, sequences, identity matrices, and uninitialized buffers.
Inspect array metadata, examine underlying data structures, and handle shape errors.
Modify array dimensions, slice sections, split arrays, and insert or append elements.
Mastering array indexing is vital for high-performance numerical computing and data manipulation. This guide explores 1D element extraction, 2D matrix row/column slicing, 3D tensor slicing with ellipses, memory views versus explicit copies, and boolean indexing. For advanced filtering and conditional selection, review Boolean Masks and where().
| Access Pattern | Syntax Example | Description |
|---|---|---|
| Basic 1D Indexing | a[i] | Extracts a single element at index i (supports negative indexing from end) |
| 1D Slicing | a[start:stop:step] | Extracts a range of elements with optional stride steps (stop is exclusive) |
| 2D Matrix Indexing | b[row, col] | Accesses specific row and column coordinates |
| 2D Axis Slicing | b[r_start:r_stop, c_start:c_stop] | Slices rows and columns simultaneously |
| 3D Tensor & Ellipsis | c[..., col] | Extracts columns across all leading dimensions using the ellipsis operator |
Unlike standard Python lists which duplicate nested structures upon slicing, NumPy slicing constructs a view over the original memory buffer. Modifying elements within a slice directly alters the underlying parent array. When complete isolation is required, the explicit .copy() method must be invoked.
The table below compares legacy NumPy indexing snippets with the updated, robust, and self-verifying implementation:
| Aspect | Legacy Implementation | Modernized Implementation |
|---|---|---|
| Code Structure | Basic unformatted code blocks with minimal explanatory text. | Structured HTML5 layout, schema-compliant TechArticle markup, and responsive tables. |
| Memory Safety | Implicit view modification without explicit warnings on side effects. | Explicit documentation of views vs. copies and memory buffer isolation via .copy(). |
| Verification | Unchecked print statements with manual result inspection. | Automated unit test assertions (assert) verifying shape and extracted values. |
| Ecosystem Integration | Isolated references. | Cross-links to boolean masks, reshape, and runnable Colab notebooks. |
Access elements in a 1-dimensional array using integer indices and slice ranges [start:stop:step]:
import numpy as np
a = np.array([10, 20, 30, 40, 50])
print("First element:", a[0]) # 10
print("Last element: ", a[-1]) # 50
# Slice range (stop index is exclusive)
print("Slice a[1:4]: ", a[1:4]) # [20 30 40]
print("Step stride: ", a[::2]) # [10 30 50]
print("Reversed: ", a[::-1]) # [50 40 30 20 10]
assert np.array_equal(a[1:4], np.array([20, 30, 40]))
Expected output
First element: 10
Last element: 50
Slice a[1:4]: [20 30 40]
Step stride: [10 30 50]
Reversed: [50 40 30 20 10]
Two-dimensional arrays use comma-separated coordinate syntax [row_selector, col_selector]:
b = np.array([
[1, 2, 3],
[10, 20, 30],
[40, 50, 60]
])
print("Element at row 0, col 1:", b[0, 1]) # 2
print("Entire row 1: ", b[1]) # [10 20 30]
print("Entire column 0: ", b[:, 0]) # [ 1 10 40]
print("Sub-matrix b[0:2, 1:3]:
", b[0:2, 1:3])
assert b[0, 1] == 2
assert b[0:2, 1:3].shape == (2, 2)
Expected output
Element at row 0, col 1: 2
Entire row 1: [10 20 30]
Entire column 0: [ 1 10 40]
Sub-matrix b[0:2, 1:3]:
[[ 2 3]
[20 30]]
For multi-dimensional tensors, the ellipsis operator (...) expands to number of `:` slices required to match the array rank:
c = np.arange(2 * 3 * 4).reshape(2, 3, 4) # shape (2, 3, 4)
print("Specific tensor slice:
", c[1, 0:2, 2:4])
print("First column across all 2D slices (c[..., 0]):
", c[..., 0])
assert c[..., 0].shape == (2, 3)
Expected output
Specific tensor slice:
[[18 19]
[22 23]]
First column across all 2D slices (c[..., 0]):
[[ 0 4 8]
[12 16 20]]
Slices in NumPy create memory views. Modifying a slice affects the source array unless .copy() is explicitly called:
a = np.array([0, 1, 2, 3, 4, 5])
s = a[1:4] # Slice creates a view sharing memory
s[0] = 99
print("Original array modified via view:", a)
# Force independent copy
s_copy = a[1:4].copy()
s_copy[0] = -1
print("Original array after isolated copy modification:", a[1:4])
assert a[1] == 99
Expected output
Original array modified via view: [ 0 99 2 3 4 5]
Original array after isolated copy modification: [99 2 3]
Pass boolean condition arrays as indices to extract filtered subsets or apply conditional mapping with np.where():
x = np.array([5, 12, 7, 22, 3, 18])
mask = x >= 10
print("Boolean mask filtered:", x[mask])
y = np.where(x < 10, 0, x)
print("np.where conditional mapping:", y)
assert np.array_equal(x[mask], np.array([12, 22, 18]))
Expected output
Boolean mask filtered: [12 22 18]
np.where conditional mapping: [ 0 12 0 22 0 18]
a[m:n] include index m but exclude index n.-1 for the final element and -2 for the penultimate element..copy() if a sliced sub-array needs to be modified independently of its parent array.IndexError: index out of bounds..copy() silently modifies source arrays, causing difficult debugging bugs..copy() on the slice.
Test 1D/2D/3D indexing, step strides, view mutation safety, and run verification test suites in our interactive Google Colab companion notebook:
Launch the notebook directly in Google Colab to run live code cells or inspect the source repository on GitHub:
View on GitHubContinue exploring related NumPy topics: Boolean Masks, where(), array(), shape, and reshape().
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.