Written and maintained by CASRAI Editorial Board
Last updated
Broadcasting in NumPy is the set of rules that lets arithmetic work on arrays of different shapes: subject to certain constraints, the smaller array is “broadcast” across the larger one so the shapes become compatible. NumPy compares shapes from the trailing (rightmost) dimension leftward, and two dimensions are compatible when they are equal or when one of them is 1. When no such alignment exists, you get ValueError: operands could not be broadcast together. This guide walks through the rule with the shapes from the NumPy manual, shows how to read the error message, and shows how to fix a mismatch with np.newaxis.
What NumPy broadcasting is used for in research
Broadcasting is how research code applies a value, a row or a column to a whole array without writing a loop. The NumPy manual describes it as a means of vectorizing array operations so that looping occurs in C instead of Python, without making needless copies of data. Typical research uses are subtracting a per-column mean from a data matrix, scaling every measurement by one constant, and building a table of all pairwise sums or differences between two vectors. Related CASRAI guides: np.where for choosing values by condition, and np.repeat for making an explicit repeated copy when you need one.
Install or access
Broadcasting is built into NumPy; there is nothing separate to enable. The official NumPy installation page lists these commands:
pip install numpyconda install numpy(inside a conda environment created withconda create -n my-envand activated withconda activate my-env)
Check the install, and see how the package is conventionally imported in import numpy as np, with:
import numpy as np
print(np.__version__)
Step-by-step: how NumPy broadcasting works
1. Add a smaller array to a larger one
The manual’s basic example adds a one-dimensional array of shape (3,) to a two-dimensional array of shape (4,3). The row b is stretched down all four rows of a:
import numpy as np
a = np.array([[0.0, 0.0, 0.0],
[10.0, 10.0, 10.0],
[20.0, 20.0, 20.0],
[30.0, 30.0, 30.0]])
b = np.array([1.0, 2.0, 3.0])
a + b
# array([[ 1., 2., 3.],
# [11., 12., 13.],
# [21., 22., 23.],
# [31., 32., 33.]])
A scalar broadcasts the same way. The manual notes that the stretching is only a conceptual picture: NumPy uses the original scalar value without actually making copies.
2. Align the shapes from the right
The two arrays need not have the same number of dimensions. The result has the number of dimensions of the largest input, each of its sizes is the largest of the corresponding input sizes, and missing leading dimensions are treated as size one. Write the shapes one above the other, right-aligned, and check each column:
| Array A shape | Array B shape | Column-by-column check (right to left) | Result |
|---|---|---|---|
| (8, 1, 6, 1) | (7, 1, 5) | 1 vs 5 ok; 6 vs 1 ok; 1 vs 7 ok; 8 vs (missing) | (8, 7, 6, 5) |
| (256, 256, 3) | (3,) | 3 vs 3 ok; the rest of A passes through | (256, 256, 3) |
| (3,) | (4,) | 3 vs 4: not equal, neither is 1 | error |
| (2, 1) | (8, 4, 3) | 1 vs 3 ok; 2 vs 4: not equal, neither is 1 | error |
The first two rows and the last two are the manual’s own examples. You can compute the result shape without building any arrays by calling np.broadcast_shapes((8, 1, 6, 1), (7, 1, 5)), which returns (8, 7, 6, 5).
3. Insert an axis with np.newaxis to build an outer sum
To combine every element of one vector with every element of another, make the first one a column. The manual’s example adds a length-4 vector and a length-3 vector:
a = np.array([0.0, 10.0, 20.0, 30.0])
b = np.array([1.0, 2.0, 3.0])
a[:, np.newaxis] + b
# array([[ 1., 2., 3.],
# [11., 12., 13.],
# [21., 22., 23.],
# [31., 32., 33.]])
In the manual’s words, the newaxis index operator inserts a new axis into a, making it a two-dimensional 4×1 array, and combining the 4×1 array with b, which has shape (3,), yields a 4×3 array. The same pattern gives all pairwise differences, which is the building block of distance matrices; for the norm step see numpy.linalg.norm.
4. Make a broadcast copy explicit with np.broadcast_to
The signature in the manual is numpy.broadcast_to(array, shape, subok=False). It broadcasts an array to a new shape:
x = np.array([1, 2, 3])
np.broadcast_to(x, (3, 3))
# array([[1, 2, 3],
# [1, 2, 3],
# [1, 2, 3]])
Output and how to read it
The output of a broadcast operation is a new array whose shape is the element-wise maximum of the aligned input shapes, as in the table above. Read the result shape first: if it is not the shape you intended, one of your inputs had the wrong orientation. A common case is a vector of shape (4,) added to a (4,3) array: it does not line up, because its single dimension is compared with the trailing dimension of size 3. The fix is to turn the vector into a column of shape (4,1), either with np.newaxis as above or with reshape:
c = np.array([1, 2, 3, 4])
c.reshape(4, 1) + np.array([10, 20, 30])
# array([[11, 21, 31],
# [12, 22, 32],
# [13, 23, 33],
# [14, 24, 34]])
Note that np.broadcast_to returns a read-only view on the original array. It is typically not contiguous, and more than one element of the broadcast array may refer to a single memory location. Writing to it raises ValueError: assignment destination is read-only, so call .copy() first if you need to modify the values (for an independent tiled copy see np.repeat).
Troubleshooting: “operands could not be broadcast together”
This ValueError means the shapes are incompatible. The message ends with the two shapes, for example:
a + np.array([1.0, 2.0, 3.0, 4.0])
# ValueError: operands could not be broadcast together with shapes (4,3) (4,)
- Copy the two shapes from the message and right-align them as in the table above.
- Find the first column, counting from the right, where the sizes differ and neither is 1. Here it is 3 against 4.
- Decide which axis you meant to pair. If the (4,) array was meant to run down the rows, make it (4,1) with
v[:, np.newaxis]orv.reshape(4, 1). - If you do not know which axis was meant, stop and inspect
.shapeon both inputs. Reshaping a 2-element array to (2,3), for instance, raises its own error, because the sizes do not multiply to match.
The manual also flags two cases where broadcasting is a poor choice. It can lead to inefficient use of memory that slows computation, for example when it creates a large intermediate array (the manual’s vector quantization example), and for such problems it recommends writing the algorithm’s outer loop in Python instead. Code that combines many broadcast dimensions can also be hard to read.
Free alternatives
NumPy is free, open-source software. These are the related tools in the same library:
| Tool | What it does | Use it when |
|---|---|---|
np.newaxis |
Inserts a new axis of size 1 into an array through indexing | You want an outer operation such as all pairwise sums |
np.broadcast_to |
Returns a read-only view of an array at a new, compatible shape | You need an array of the target shape without copying the data |
np.broadcast_shapes |
Returns the shape that broadcasting the given shapes would produce | You want to check compatibility before building arrays |
| Python outer loop | Processes one slice at a time | The manual says a full broadcast would create a very large intermediate array |
FAQ
What is broadcasting in NumPy?
It is how NumPy treats arrays with different shapes during arithmetic: the smaller array is broadcast across the larger array so that they have compatible shapes, and the looping happens in C instead of Python.
What are the numpy broadcasting rules?
Compare the shapes from the trailing dimension toward the front. Two dimensions are compatible if they are equal or if one of them is 1. Missing leading dimensions count as size one.
Does broadcasting copy the data?
Not in the way the stretching picture suggests. The manual says the stretching is only conceptual and that NumPy uses the original value without making copies. It also warns that some broadcasts create large intermediate arrays that waste memory.
Why does a (4,) array not add to a (4,3) array?
Its only dimension is compared with the trailing dimension of size 3, and 4 and 3 are neither equal nor 1. Reshape it to (4,1) first.
Sources
- NumPy documentation, Broadcasting (user guide), checked 2026-10-29.
- NumPy documentation, numpy.broadcast_to, checked 2026-10-29.
- NumPy, Installing NumPy, checked 2026-10-29.
The code on this page was run on NumPy 2.5.1 and the outputs match those shown.







