NumPy Indexing & Reshaping
Indexing selects and rearranges ndarray data along axes; reshaping changes shape without changing values when the total size stays constant.
Recipe
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:
- Extracting submatrices for batch processing
- Reordering dimensions before passing data to ML models
- Building masks for conditional updates
- Aligning shapes for broadcasting across axes
Working Example
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:
- Column slicing with
start:stoponaxis=1 - Reduction along
axis=1thenargsortfor row selection .Ttranspose as a reshape shortcutnp.whereonmax(axis=0)to index columns by condition
Deep Dive
How It Works
- Basic slicing (
start:stop:step) uses strides to produce a view sharing memory. - Integer array indexing gathers elements in arbitrary order and usually copies.
- Boolean masks must match broadcastable shape;
arr[mask]returns a 1-D selection. reshapereturns a view when strides allow; otherwise it copies.
Indexing Modes
| 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 Conventions
axis | 2-D meaning |
|---|---|
0 | Down rows (aggregate columns) |
1 | Across columns (aggregate rows) |
-1 | Last dimension |
Python Notes
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()Gotchas
- Assigning through fancy index -
a[[0, 1]] = 5may not behave like repeated slice assignment. Fix: assign to.copy()or usenp.put. - Negative strides views - reversing with
a[::-1]can make some reshapes copy unexpectedly. Fix: call.copy()before downstream C extensions. - Boolean mask shape -
a[mask]on 2-D needs mask shape(rows, cols)or broadcastable. Fix:mask = mask & (a > 0)with aligned shapes. - Off-by-one slices -
a[1:3]excludes index 3; unlikerange. Fix: remember stop is exclusive. - reshape size mismatch -
reshape(3, 5)on 12 elements raises. Fix: use-1for one inferred dimension:reshape(3, -1).
Alternatives
| 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 |
FAQs
What is the difference between view and copy?
- Views share data buffer; copies are independent.
- Mutating a view affects the parent unless you copied first.
How do I select every other row?
import numpy as np
a = np.arange(10)
every_other = a[::2]How do I swap rows and columns?
matrix.Tornp.transpose(matrix)for 2-D.np.swapaxes(a, 0, 1)when rank > 2.
Can reshape change total elements?
- No - total size must match:
np.prod(shape) == a.size. - Use
np.resizeonly when you intentionally want repetition or truncation.
How do I index a 3-D volume?
vol[z, y, x]- slowest axis first in C order.- Document axis meaning in function docstrings.
Why does flat indexing differ from 2-D?
a[5]on 2-D uses C-order ravel index.- Prefer
a[row, col]ornp.unravel_indexfor clarity.
How do I filter and keep 2-D shape?
- Boolean mask on rows:
a[mask, :]keeps columns intact. a[mask]alone always flattens selected elements to 1-D.
What does ellipsis `...` do?
a[..., 0]selects index 0 on the last axis, all prior axes full.- Useful for N-D arrays without listing every colon.
How do I stack vs concatenate?
np.stackadds a new axis;np.concatenatejoins along an existing axis.np.vstack/hstackare convenience wrappers.
Is x[i, j] the same as x[(i, j)]?
- Yes for ndarray - tuple index lists dimensions.
x[i][j]indexes twice and can break on non-square structures.
Related
- NumPy Arrays - creation, dtypes, broadcasting
- pandas Series & DataFrames -
.loc/.ilocanalogs - Performance & Memory - views vs copies at scale
- Data Analysis Basics - intro examples
Stack 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+.