Basic Prerequisites: 01 · From Zero and Linear Algebra & Matrices.


1. Intuition & Practical Objective

NumPy is where the stack’s speed actually lives. The practical objective of this page: write every numeric computation as whole-array expressions in C, use broadcasting to avoid explicit loops, and know precisely when NumPy gives you a view (writes propagate) versus a copy (writes are silently discarded). Master those three and you have unlocked the 50–150× that the whole stack is built on.

Three ideas anchor everything:

  1. Elementwise ops happen in C, not in Python. 2.0*x + 1.0 on a 5M-element array is one compiled pass over a contiguous typed buffer, not 5M interpreted dispatches. That single fact is why vectorization is ~80× faster in the verified benchmark below.
  2. Broadcasting lets one expression handle many shapes. NumPy aligns arrays of compatible shapes so a scalar, a column vector, and a row vector combine without a single loop you write. It is the shape-level generalization of vectorization - essential for normalizing a matrix of returns, scaling a position vector, or adding a term-structure curve to a panel.
  3. A view shares memory with its base; a copy does not. Slicing (x[::2], x[1:5]) returns a view - cheap, zero-copy, and writes propagate back to x. Fancy indexing (x[[0,2,4]]) and any boolean-mask indexing return a copy. Getting this backwards is the #1 silent data-corruption bug in the stack.

Why it matters for quant. Signals, returns, positions, and equity are all arrays. A well-vectorized backtest is a constant number of whole-array passes (01), and normalizing/standardizing a panel of returns across thousands of assets is a broadcasting one-liner rather than an asset-by-asset loop.


2. Mathematical Ground Truth & Derivations

The speedup model. For elements with per-element interpreted cost and compiled cost , vectorization gives

The benchmark in §3 measures for 2x+1, i.e. ~1–2 orders of magnitude - exactly the predicted range.

Broadcasting rules. Two arrays are broadcast-compatible when, comparing trailing dimensions, each pair is equal, or one of them is 1. For the z-score normalization of a returns panel against column means and column stds :

The (T,K) array broadcasts against the length-K vectors along the last axis - no per-asset loop.

Views vs copies - the exact rules. Indexing that selects a contiguous-addressable regular subset of the base (slices x[2:8], stepped x[::2], x[:, 1]) yields a view: np.shares_memory(view, base) == True, zero-copy, writes propagate. Indexing by fancy arrays (x[[0,2,4]]) or boolean masks (x[x>0]) yields a copy because the selected elements are not a contiguous stride-accessible window. The verified demo in §3 shows np.shares_memory reporting exactly this split.


3. Computational Implementation - the vectorization speedup, reproduced

A. Elementwise: Python loop vs NumPy (the headline number).

B. Broadcasting: z-scoring a returns panel, double-loop vs one line.

C. Views vs copies - the memory-sharing split, proven.

The copy in (C) is the same mechanism behind the pandas chained-assignment trap (03): indexing selects a copy, and writing to that copy vanishes.


4. Failure Modes & First-Principles Breakdowns

  1. Fancy/boolean indexing returns a copy, not a view. Writing x[mask] = v is correct (assignment through the mask), but y = x[mask]; y[0] = v modifies the copy - x is unchanged. This silent loss is the vector analogue of pandas’ chained assignment.
  2. int32 overflow is silent. np.int32(2_000_000_000) + np.int32(2_000_000_000) yields -294,967,296 with only a RuntimeWarning - see the dtype trap in 05 · Failure Modes. Know your input dtypes; upcast to int64/float64 for anything that can grow.
  3. Broadcasting surprises. Shapes that are not compatible raise ValueError loudly (good), but a shape like (T,1) vs (K,) can broadcast in an unintended axis. Check .shape on the result of any nontrivial broadcast.
  4. Vectorization trades memory for speed. Every intermediate (M - mean, / std) is a materialized array; for very large panels this can exhaust RAM (the production-limit discussion in 06).

5. References

  • McKinney, Python for Data Analysis (3rd ed., 2022)
  • Hilpisch, Python for Finance (2nd ed., 2018)
  • NumPy official docs - “Array Broadcasting” and “Copies and Views” (numpy.org/doc/stable)

6. Connected Graph Bridges