The Analyst's Path

Phase 12 · Finance Plus, AI and the quant-code track · free

NumPy & Vectorized Computation

DA1.01 · 13,913 words

> The duality, stated once (R10). Objectives 1–10 are the understanding objective: the gate (quiz ≥ 85%, code-pack ≥ 85% with hidden tests green) rewards being able to trace shapes, predict broadcasting outcomes, and write correct vectorized code yourself.

Learning objectives

By the end you can:

  1. Explain why a NumPy array outperforms a native Python list for numeric work, contiguous, single-dtype memory and vectorized operations that run as a tight, compiled loop instead of the Python interpreter stepping through one element, one bytecode dispatch, at a time, and predict, before running anything, that a vectorized operation on a real-sized array will be an order of magnitude (or more) faster than the equivalent explicit loop.
  2. Create and inspect ndarrays: np.array, np.zeros/np.ones/np.arange/np.linspace, and read off an array's shape, dtype, ndim, and size to predict what any expression involving it will produce, including when np.asarray copies data and when it does not.
  3. Correctly predict whether a given indexing operation (basic slicing versus fancy (integer-list) or boolean indexing) returns a view (shares memory with the original; mutating it mutates the original) or a copy (independent; mutating it does nothing to the original), and use this to explain why a chained indexing assignment can silently do nothing at all.
  4. Write elementwise vectorized arithmetic and comparison expressions (ufuncs) with no explicit loop, and use a boolean mask to filter and then aggregate in one line (returns[returns > 0].mean()).
  5. State NumPy's broadcasting rule precisely, align shapes from the trailing dimension; two dimensions are compatible when they are equal, or when one of them is 1, and use it to predict, before running code, whether two given shapes will broadcast together, what the result shape will be, or that NumPy will raise a ValueError.
  6. Perform axis-aware reductions (sum/mean/std/min/max/cumsum/cumprod, axis=0 vs. axis=1) and correctly diagnose the classic np.cov rowvar trap on (days, tickers)-shaped return data, where the default silently computes the wrong-shaped result.
  7. Use matrix multiplication (@) to turn a returns matrix and a weight vector into a vector of per-day portfolio returns, and a quadratic form (weights @ cov_matrix @ weights) to compute portfolio variance, strictly as NumPy mechanics, not portfolio theory.
  8. Detect and avoid three concrete dtype/NaN pitfalls: silent integer overflow in fixed-width dtypes, an in-place true-division cast error on integer arrays, and NaN silently propagating through an ordinary .mean()/.sum() with no error at all.
  9. Generate reproducible pseudo-random arrays with NumPy's modern Generator API (np.random.default_rng(seed)) and explain why a fixed seed is exactly what makes a hidden test, or a report: deterministic and re-runnable.
  10. Apply everything above to the module's running problem: given price and return data from an Indian (₹, NSE-style) and a US ($, NYSE-style) snapshot, compute vectorized returns, cumulative growth, a standardized return matrix, a covariance matrix, and portfolio variance, first by hand on a small case, then in real, running, tested NumPy code (this module's code pack, DA1.01).
  11. (Productivity objective: R10 duality.) Use an AI coding assistant to scaffold NumPy boilerplate for parts of a task you already understand by hand, while never trusting an AI-generated axis, rowvar, or broadcasting choice without tracing the shapes yourself and running this module's tests.

The duality, stated once (R10). Objectives 1–10 are the understanding objective: the gate (quiz ≥ 85%, code-pack ≥ 85% with hidden tests green) rewards being able to trace shapes, predict broadcasting outcomes, and write correct vectorized code yourself. Objective 11 is the productivity objective: knowing how a real developer uses a copilot on top of that understanding, never instead of it. An assistant can generate a plausible-looking np.cov(matrix) in half a second, it cannot tell you, and will not warn you, that it just silently computed the wrong shape. Only tracing the shape yourself, and running this module's hidden tests, can.


Prerequisites & connections

Builds on. Nothing is a hard prerequisite gate, like every branch's first node, DA1.01 unlocks from day one. But this module assumes real fluency with core Python at roughly CS1.01/CS1.02's level: variables, functions with return, lists, indexing, and if/for/while control flow. If writing a small function or tracing a loop by hand still feels shaky, spend an hour in CS1.01 first, this module does not re-teach those fundamentals (R1), it immediately builds a new layer on top of them: the array object, and the habit of describing a computation once, over a whole array, instead of one element at a time. No calculus and no linear-algebra background is assumed; the two matrix operations this module uses (matrix multiplication and a quadratic form) are taught here from the ground up, mechanically, with no theory beyond "here is what shape goes in and what shape comes out."

This page is an excerpt

The full module runs to 13,913 words and carries the worked examples, the tables, the quiz that gates the next module and the spaced-repetition deck built from it. All of it is free and none of it needs an account.