Broadcasting
How NumPy makes mismatched shapes work — without copying anything.
shape rulesnp.newaxisouter operationsValueErrorWatch it happen
Play it through, or step back and forth yourself.
baserowbase is (3, 4). row is (4,) — just four values. Adding them looks like it shouldn't work: the shapes don't match.
The idea
a * 2 works, and nobody finds that strange — the 2 is obviously applied to everything. Broadcasting is that same idea taken seriously, and once you see it that way the rules stop feeling arbitrary.
The rule, in full
NumPy lines the two shapes up from the right and compares them axis by axis. A pair is compatible if the lengths are equal, or if one of them is 1. Missing axes on the left are treated as 1. Any pair that fails means the whole thing fails.
(3, 4) and (4,) -> (3, 4) 4 matches 4; 3 pairs with nothing = 1
(3, 4) and (3, 1) -> (3, 4) 1 stretches to 4
(3, 4) and (3,) -> ERROR 4 vs 3, and neither is 1
(3, 1) and (1, 4) -> (3, 4) both stretch — an outer operationThat third line is the one people hit. A (3,) lines up against the last axis, which has length 4 — so it fails, even though 3 "looks like" it should match the rows. If you meant it to go down the rows, say so by giving it a second axis: col[:, None] makes it (3, 1), and now it stretches across instead.
Nothing is copied
This is the part worth carrying away. When a length-1 axis stretches, NumPy does not build the expanded array. It reads the same values repeatedly, using a stride of zero along the stretched axis. Broadcasting a small array against a huge one costs no extra memory at all.
Which is exactly why the stretched cells in the animation are drawn hollow: logically present, physically absent.
What it's for
Once it clicks you'll use it constantly — centring data by subtracting a per-column mean, scaling rows, building a multiplication table without a single loop:
cups - cups.mean(axis=0) # centre each stall
np.arange(1, 4)[:, None] * np.arange(1, 5) # (3,1) x (1,4) -> (3,4)And when it goes wrong, the error tells you plainly: operands could not be broadcast together with shapes (3,4) (3,). Read the two shapes, line them up from the right, and find the pair that isn't equal-or-1.
Practice
Write it yourself. The answer is there when you want it.
Putting the kettle on…
Starting up…
Write it yourself
not gradedBuild a (3, 4) whose rows are all 0s, all 10s and all 20s, and a row [1, 2, 3, 4]. Add them and print the result. Then take a column of three values instead: adding it straight fails, so use [:, None] to stand it up first.
Your turn
3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.
Add v to every row of a. Both are already the right shapes.
Add np.array([100, 200, 300]) down the rows of a — so row 0 gains 100, row 1 gains 200, row 2 gains 300.
Subtract each stall's mean from cups, so every column ends up centred on zero.
