Topic 5 Broadcasting
Topic 5 Broadcasting
[3]: a + 5
[5]: M + a
Here the one-dimensional array a is stretched, or broadcast across the second dimension in order
to match the shape of M.
[6]: a = np.arange(3)
b = np.arange(3)[:, np.newaxis]
print(a)
1
print(b)
[0 1 2]
[[0]
[1]
[2]]
[7]: a + b
The light boxes represent the broadcasted values: again, this extra memory is not actually
allocated in the course of the operation, but it can be useful conceptually to imagine that it
is.
2
• Rule 2: If the shape of the two arrays does not match in any dimension, the array with shape
equal to 1 in that dimension is stretched to match the other shape.
• Rule 3: If in any dimension the sizes disagree and neither is equal to 1, an error is raised.
To make these rules clear, let’s consider a few examples in detail.
Let’s consider an operation on these two arrays. The shape of the arrays are
• M.shape = (2, 3)
• a.shape = (3,)
We see by rule 1 that the array a has fewer dimensions, so we pad it on the left with ones:
• M.shape -> (2, 3)
• a.shape -> (1, 3)
By rule 2, we now see that the first dimension disagrees, so we stretch this dimension to match:
• M.shape -> (2, 3)
• a.shape -> (2, 3)
The shapes match, and we see that the final shape will be (2, 3):
[9]: M + a
3
• a.shape -> (3, 1)
• b.shape -> (1, 3)
And rule 2 tells us that we upgrade each of these ones to match the corresponding size of the other
array:
• a.shape -> (3, 3)
• b.shape -> (3, 3)
Because the result matches, these shapes are compatible. We can see this here:
[11]: a + b
This is just a slightly different situation than in the first example: the matrix M is transposed. How
does this affect the calculation? The shape of the arrays are
• M.shape = (3, 2)
• a.shape = (3,)
Again, rule 1 tells us that we must pad the shape of a with ones:
• M.shape -> (3, 2)
• a.shape -> (1, 3)
By rule 2, the first dimension of a is stretched to match that of M:
• M.shape -> (3, 2)
• a.shape -> (3, 3)
Now we hit rule 3–the final shapes do not match, so these two arrays are incompatible, as we can
observe by attempting this operation:
[13]: M + a
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
4
/tmp/ipykernel_23560/3374645918.py in <module>
----> 1 M + a
ValueError: operands could not be broadcast together with shapes (3,2) (3,)
[14]: (3, 1)
We can compute the mean of each feature using the mean aggregate across the first dimension:
[17]: Xmean = X.mean(0)
Xmean
And now we can center the X array by subtracting the mean (this is a broadcasting operation):
To double-check that we’ve done this correctly, we can check that the centered array has near zero
mean:
[19]: X_centered.mean(0)
5
[20]: # x and y have 50 steps from 0 to 5
x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 50)[:, np.newaxis]