Broadcasting lets NumPy apply an operator to arrays with different dimensions, including an array and a scalar. Instead of creating a 100,000-element array of ones to increment another array, use `array_100000 += 1`. The scalar is applied across the array without constructing that matching input. section 4.2.2
A Python loop that adds arrays element by element needs its own shape checks and output handling. NumPy operators provide a more concise array-programming alternative, but shapes still matter: not every pair of arrays is compatible. section 4.2.2 section 4.4
Check what operation you are asking NumPy to perform:
- `a + 1` and `a * 2` apply a scalar across a one-dimensional array; `a + [10, 2, 25, 5]` and `a * [10, 2, 25, 5]` operate element by element when the shapes fit. section 4.2.2
- For a two-column matrix, `x + [1, 2]` applies the two values across its rows. Transposing before addition provides a way to apply values along the other dimension. section 4.2.2
- Do not confuse elementwise operators with inner products or matrix multiplication: `dot`, `inner`, and `@` express different computations. section 4.2.2
Brighten an image without ignoring dtype or memory
An image stored as unsigned bytes can be brightened with `image_arr + 5`, but doubling values in that dtype can produce an unexpected result. Convert to `np.uint16`, double, clamp each value with `np.minimum(brighter3_arr, 255)`, then convert back to `np.uint8`. The scalar limit is broadcast across the array; `np.minimum` creates a result array. Where mutation is appropriate, `x *= 2` avoids the intermediate array created by `x = x * 2`. section 4.2.3
Broadcasting support alone is not a speed guarantee. `np.vectorize` supports broadcasting rules, yet a timed vectorized Python function ran in milliseconds where array multiplication ran in microseconds. For RGB-to-grayscale conversion, a mean over the color-channel axis is preferable to a custom vectorized function. section 4.2.4


