Broadcasting is the set of rules that decides how an array operation should behave when its operands have different shapes. Without it, adding a single number to every row of a matrix, or scaling each column by a different factor, would require first manually expanding the smaller operand to match the larger one. Broadcasting makes that expansion implicit: the smaller array is treated as if it were stretched to the larger array’s shape, so the operation just works, and it does so without actually allocating the stretched copy.
The NumPy documentation introduces it directly: “The term broadcasting describes how NumPy treats arrays with different shapes during arithmetic operations. Subject to certain constraints, the smaller array is ‘broadcast’ across the larger array so that they have compatible shapes.” The compatibility test is compact. Comparing the shapes from the trailing dimension backward, two dimensions are compatible when, in the documentation’s words, “they are equal, or one of them is 1.” A dimension of size 1 is the signal that means “repeat me along this axis as needed.”
A concrete case shows the convenience. Adding a one-dimensional array of shape (3,) to a two-dimensional array of shape (4, 3) succeeds because the trailing dimensions match; the length-3 array is broadcast across all four rows. The key efficiency point is that this stretching is conceptual only. NumPy does not build a (4, 3) copy of the small array - it loops over the large array and reuses the small array’s elements in place, so broadcasting adds no memory cost and no copying overhead.
Broadcasting is tightly bound to vectorization and the universal-function machinery. Because ufuncs operate element by element, they need a rule for pairing up elements when shapes differ, and broadcasting supplies it. This lets a single concise expression express operations that would otherwise demand nested loops or explicit tiling, keeping numerical code both short and fast.
The convention proved so useful that it spread far beyond NumPy. PyTorch, TensorFlow, and JAX all adopted the same semantics - trailing-dimension alignment with size-1 stretching - so that knowledge of the rule transfers across the whole ecosystem. Broadcasting is one of those small design decisions that quietly shapes how an entire field writes code: once it exists, array math is written in terms of shapes that “fit” rather than shapes that must be made to match by hand.