NumPy Indexing & Reshaping
Indexing selects and rearranges ndarray data along axes; reshaping changes shape without changing values when the total size stays constant.
Search across all documentation pages
Indexing selects and rearranges ndarray data along axes; reshaping changes shape without changing values when the total size stays constant.
Quick-reference recipe card - copy-paste ready.
import numpy as np
matrix = np.arange(12).reshape(3, 4)
rows = matrix[1:3, ::2] # slice rows 1-2, every other column
cols = matrix[:, [0, 3]] # fancy index columns 0 and 3
flat = matrix.reshape(-1) # 1-D view when possibleWhen to reach for this:
import numpy as np
# 4 regions x 6 months
sales = np.array(
[[10, 12, 11, 13, 14, 15],
[8, 9, 10, 9, 11, 12],
[20, 18, 19, 21, 22, 23],
[5, 6, 5, 7, 6, 8]],
dtype=np.int32,
)
# Q1 only: months 0-2, all regions
q1 = sales[:, 0:3]
# Top two regions by total sales
totals = sales.sum(axis=1)
top_idx = np.argsort(totals)[-2:]
top_regions = sales[top_idx]
# Stack region vectors as columns for correlation
wide = sales.T # shape (6, 4) - months as rows
# Flag months where any region beat 20
hot_months = np.where(sales.max(axis=0) >= 20)[0]
print("q1 shape:", q1.shape)
print("top regions:", top_idx)
print("hot months:", hot_months)What this demonstrates:
start:stop on axis=1axis=1 then argsort for row selection.T transpose as a reshape shortcutnp.where on max(axis=0) to index columns by conditionstart:stop:step) uses strides to produce a view sharing memory.arr[mask] returns a 1-D selection.reshape returns a view when strides allow; otherwise it copies.| Style | Example | Copy? |
|---|---|---|
| Slice | a[2:5] | Usually view |
| Integer list | a[[1, 3]] | Copy |
| Boolean mask | a[a > 0] | Copy |
np.take | np.take(a, idx, axis=0) | Configurable |
axis | 2-D meaning |
|---|---|
0 | Down rows (aggregate columns) |
1 | Across columns (aggregate rows) |
-1 | Last dimension |
import numpy as np
# Insert axis for broadcasting
row = np.array([1, 2, 3])
col = row[:, np.newaxis] # shape (3, 1)
# ravel vs flatten: flatten always copies
a = np.arange(6).reshape(2, 3)
flat_view = a.ravel()
flat_copy = a.flatten()a[[0, 1]] = 5 may not behave like repeated slice assignment. Fix: assign to .copy() or use np.put.a[::-1] can make some reshapes copy unexpectedly. Fix: call .copy() before downstream C extensions.a[mask] on 2-D needs mask shape (rows, cols) or broadcastable. Fix: mask = mask & (a > 0) with aligned shapes.a[1:3] excludes index 3; unlike range. Fix: remember stop is exclusive.reshape(3, 5) on 12 elements raises. Fix: use -1 for one inferred dimension: reshape(3, -1).| Alternative | Use When | Don't Use When |
|---|---|---|
np.einsum | Explicit tensor contractions | Simple row/column picks |
pandas .loc | Labeled rows/columns | Pure numeric ndarray kernels |
np.take_along_axis | Sorting values per row | Whole-matrix slices suffice |
np.moveaxis | Reordering 3-D+ tensors | Simple .T on 2-D |
import numpy as np
a = np.arange(10)
every_other = a[::2]matrix.T or np.transpose(matrix) for 2-D.np.swapaxes(a, 0, 1) when rank > 2.np.prod(shape) == a.size.np.resize only when you intentionally want repetition or truncation.vol[z, y, x] - slowest axis first in C order.a[5] on 2-D uses C-order ravel index.a[row, col] or np.unravel_index for clarity.a[mask, :] keeps columns intact.a[mask] alone always flattens selected elements to 1-D.a[..., 0] selects index 0 on the last axis, all prior axes full.np.stack adds a new axis; np.concatenate joins along an existing axis.np.vstack / hstack are convenience wrappers.x[i][j] indexes twice and can break on non-square structures..loc / .iloc analogsStack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026