Broadcasting

Stretch size-1 axes, newaxis, and broadcast_shapes.

Broadcasting stretches size-1 axes so two arrays can meet. A length-3 price vector multiplies every row of a 5×3 units grid.

Goal

Multiply a grid by a 1-D price vector, by a column of weights, and print broadcast_shapes.

Trailing axis: prices per product

# Rows: Nairobi, Mombasa, Kisumu, Nakuru, Eldoret  ·  cols: A, B, C
units = np.array(
    [
        [12, 7, 2],
        [9, 6, 0],
        [3, 11, 1],
        [10, 8, 0],
        [6, 4, 0],
    ],
    dtype=float,
)
prices = np.array([10.5, 22.0, 31.0])
print("units", units.shape, "prices", prices.shape)
print("broadcast:", np.broadcast_shapes(units.shape, prices.shape))
revenue = units * prices
print(revenue)

(5, 3) and (3,) meet as (5, 3). Each row is multiplied by the same three prices.

Column weights with newaxis

units = np.array(
    [
        [12, 7, 2],
        [9, 6, 0],
        [3, 11, 1],
        [10, 8, 0],
        [6, 4, 0],
    ],
    dtype=float,
)
# One weight per city (Nairobi … Eldoret)
weights = np.array([1.0, 1.1, 0.9, 1.0, 1.05])
print(weights.shape)
print(weights[:, np.newaxis].shape)
print(units * weights[:, np.newaxis])

weights[:, np.newaxis] is (5, 1) so it stretches across three products.

Shapes that refuse

units = np.array([[12, 7, 2], [9, 6, 0]], dtype=float)
bad = np.array([1.0, 2.0])
try:
    print(units * bad)
except ValueError as err:
    print(err)

(2, 3) and (2,) do not align on the trailing axis. Reshape bad to (2, 1) if you meant a column.

Pitfall

A 1-D array is treated as a row against a 2-D grid. City weights need [:, np.newaxis] (a column). Product prices can stay (3,).