ndarray Fundamentals
ndarray Fundamentals
A NumPy array is a homogeneous, fixed-type, contiguous block with a shape:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) # 2×3, default float64
np.zeros((2, 4)); np.ones(5, dtype=np.int32)
np.arange(0, 10, 2) # [0 2 4 6 8]
np.linspace(0, 1, 5) # 5 evenly spaced floats
a.shape, a.dtype, a.ndim, a.size
a[0, 1], a[:, 0], a[1, :] # row/col slicing
Basic slicing returns a view — v = a[0]; v[0] = 99 changes a too — because views share the same memory with new strides. Type is uniform: mixing Python objects forces dtype=object, which forfeits nearly all speed. Build matrices with np.eye/np.diag, random with np.random.default_rng(seed) for reproducibility.
Vectorization and Broadcasting
Vectorization and Broadcasting
Broadcasting compares shapes right-to-left: dimensions are compatible when equal or one of them is 1.
m = np.ones((3, 4))
m * 2 # scalar stretches over the whole array
row = np.array([10, 20, 30, 40])
m + row # (3,4) + (4,) → row broadcasts across rows
col = np.array([[1.], [2.], [3.]])
m * col + row # outer-ish combos without nested loops
Common reductions and transforms:
m.mean(), m.sum(axis=0) # column totals; axis=1 → per row
np.sqrt(m); np.exp(m); np.where(m > 0.5, 1.0, 0.0)
mask = m[m > 0.5] # boolean masking selects elements
One expression replaces an entire nested loop — the operation runs in compiled C over contiguous memory with no per-element Python dispatch, which is where the 10–100× speedups come from.
Views, Copies, and Numerical Pitfalls
Views, Copies, and Numerical Pitfalls
- View vs copy: slicing and
reshapereturn views; boolean/fancy indexing returns copies. Call.copy()when independence matters. - dtype defaults: floats default to
float64, integers to platformint_— passdtype=np.float64to reductions explicitly when width matters. - NaN propagates: one
np.nanpoisonsmean()— usenp.nanmean/np.nansum, and remember comparisons with NaN are always False. - Shape errors are loud: mismatched non-1 dimensions raise
ValueError; transpose with.Tor[:, None]to force alignment. - Never grow arrays in a loop — preallocate or collect in a list and convert once.
Interview angle: give the broadcasting rule in one sentence, show an outer-product example, and name the view/copy distinction as a common mutation bug.
Quiz
1. What does broadcasting require when adding shapes (3,4) and (4,)?
2. b = a[0]; b[0] = 99 — what happens to a?
3. Why does np.mean() return nan when data contains one nan?
Flashcards
Question
Broadcasting rule
Click to reveal answer
Answer
Align shapes from the right; each dim must match or be 1, then size-1 axes stretch.
Question
View vs copy
Click to reveal answer
Answer
Slicing/reshape → view sharing memory; boolean/fancy indexing → copy.
Question
axis parameter
Click to reveal answer
Answer
axis=0 collapses rows (per-column), axis=1 collapses columns (per-row).
Question
Default dtype
Click to reveal answer
Answer
float64 for float input, platform int for ints — cast explicitly when precision or width matters.
Revision Notes
Key Takeaways
- 1. ndarrays: homogeneous, shaped, strided memory — views share it, copies do not
- 2. Broadcasting eliminates Python loops: align from the right, stretch size-1 dimensions
- 3. Watch NaN propagation, dtype defaults, and accidental view mutations
Interview Tips
- • State broadcasting in one sentence and work a (3,4)+(4,) example on the spot
- • Explain why vectorization is faster (contiguous C loops, no per-element dispatch), not just "it is faster"
Cheat Sheet
np.array/zeros/arange; shape/dtype/axis; broadcasting: right-align, match-or-1; slicing=view, mask=copy; nan→nanmean; preallocate, never grow in loop.
Continue Learning
Before You Start
- No prerequisites listed.