12. NumPy Broadcasting

Chapter 12 of 36 · 20 min

What Is Broadcasting

Broadcasting extends arrays with smaller dimensions to match larger ones. This eliminates explicit loops.

# Add scalar to array
arr = np.array([1, 2, 3])
print(arr + 10)  # [11, 12, 13] - scalar 10 becomes [10, 10, 10]

Broadcasting Rules

Two arrays broadcast if:

  1. Their dimensions match, or
  2. One of the dimensions is 1
# Example: Add 1D array to 2D array
a = np.array([[1, 2, 3], [4, 5, 6]])  # shape (2, 3)
b = np.array([10, 20, 30])            # shape (3,)

# b broadcasts to [[10, 20, 30], [10, 20, 30]]
print(a + b)  # [[11, 22, 33], [14, 25, 36]]

Normalizing Data

Broadcasting makes normalization trivial:

# Normalize rows to have mean 0
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
row_means = data.mean(axis=1, keepdims=True)  # shape (3, 1)
normalized = data - row_means
print(normalized.mean(axis=1))  # ~[0, 0, 0]

Outer Products

vec = np.array([1, 2, 3])
outer = vec[:, np.newaxis] * vec[np.newaxis, :]
# [[1, 2, 3],
#  [2, 4, 6],
#  [3, 6, 9]]

Common Pitfalls

Shape mismatch:

a = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
b = np.array([1, 2])                  # (2,)

try:
    print(a + b)
except ValueError as e:
    print(f"Error: {e}")
# ValueError: operands could not be broadcast together

Solution: reshape or add dimensions:

b = np.array([1, 2])[:, np.newaxis]  # (2, 1)
print(a + b)  # Works - b broadcasts to (2, 3)

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Create a matrix of predictions (3 samples, 4 classes each). Subtract the per-sample mean to center the predictions around zero. Verify each row now has mean ~0.