The broadcasting rules
What it is
Shapes are compared from the right. Two axes are compatible if they are equal, or if one of them is 1, in which case that axis is stretched. Missing leading axes count as 1.
Why it matters
It is what makes 'subtract the column mean from every row' one expression rather than a loop, and it is the mechanism under every pairwise similarity matrix you will write.
In the real world: Applying a different discount to each of 10 products across 365 days of prices in one line, without writing a loop.
Visual example
BroadcastingA (3, 1) column and a (1, 4) row broadcast into a (3, 4) grid: each length-1 axis is stretched to the other's length.
Four of the twelve cells
[0, 0] = 10 + 1 = 11
[0, 3] = 10 + 4 = 14
[2, 0] = 30 + 1 = 31
[2, 3] = 30 + 4 = 34
Why this matters
Every pairwise matrix — distances, IoU, similarity between two sets of vectors — is this picture. A column against a row gives you every combination with no loop and no index arithmetic.
Common misconception
Wrong idea: shapes must match, or you have to tile the smaller one with np.repeat.
Correct idea: a length-1 axis is stretched for free. No copy is made; the same value is read repeatedly.
- 1Align from the right
(3, 1)against(1, 4): compare 1 with 4, then 3 with 1. - 2Stretch the 1sEach axis of length 1 is read repeatedly to match the other.
- 3Compute element-wiseThe result's shape is the per-axis maximum:
(3, 4).
col = np.array([[10], [20], [30]]) # (3, 1)
row = np.array([[1, 2, 3, 4]]) # (1, 4)
(col + row).shape # (3, 4)
X = np.zeros((100, 8))
X - X.mean(axis=0) # (100, 8) - (8,) -> fine
np.broadcast_shapes((3, 1), (1, 4)) # (3, 4), without allocatingTwo shapes that broadcast when you meant them to match. Subtracting a (100,) row of per-sample values from a (100, 8) matrix raises, but a (8,) array of per-feature values subtracted when you meant per-sample succeeds and is wrong.
Practise it: Clip Outliers to a Percentile Range, Cosine Similarity Without Loops, Normalise Rows to Unit Length, One-Hot Encode a Label Vector, Pairwise Euclidean Distances, Scale Every Column to 0 and 1, Intersection Over Union for Every Box Pair, Softmax That Does Not Overflow