runtime
203 / 250
lesson 203 NumPy Foundations · advanced

Broadcasting

Arithmetic on arrays works value by value. When the shapes differ, NumPy stretches the smaller one across the larger, if the broadcasting rule allows it.

You'll be able to
  • Do element-wise arithmetic between an array and a number, and between two arrays of one shape
  • Apply the broadcasting rule: compare shapes from the right; each pair must be equal or contain a 1
  • Turn a 1-D array into a column with [:, None] to combine it with every row
The idea

tmax * 9 / 5 + 32 converts a whole week of Celsius readings to Fahrenheit in one expression: the numbers 9, 5 and 32 are used with every value. Two arrays of the same shape combine position by position, so tmax - tmin is each day's temperature range. No loop, and no index to get wrong.

Run each example to see what it prints. Running examples doesn't count toward progress.

example-1.py · Fahrenheit and the daily range
import numpy as np

tmax = np.array([-0.5, 6.7, 9.4, 7.2, 1.7])   # Wichita, 1 to 5 January 2024
tmin = np.array([-5.5, -4.9, -4.9, -2.1, 0.0])
print(tmax * 9 / 5 + 32)
print(tmax - tmin)

This stretching is called broadcasting, and it also works between arrays of different shapes. The rule: line the shapes up from the right; each pair of sizes must be equal, or one of them must be 1 (a size-1 dimension is stretched). Order totals of shape (4,) and three exchange rates of shape (3,) fail the rule: 4 and 3 are neither equal nor 1.

example-2.py · Four totals, three rates
import numpy as np

totals = np.array([35.84, 91.47, 55.72, 246.6])
rates = np.array([1.0, 0.92, 0.79])
print(totals.shape, rates.shape)
print(totals * rates)
example-3.py · Every total in three currencies
import numpy as np

totals = np.array([35.84, 91.47, 55.72, 246.6])   # Runtime Market orders, in USD
rates = np.array([1.0, 0.92, 0.79])                # example rates: USD, EUR, GBP per dollar
column = totals[:, None]
print(column.shape, rates.shape)
table = column * rates
print(table.shape)
print(table.round(2))

When to use it: a constant for every value (unit conversion, a discount), a row of per-column values for every row, or a column of per-row values for every column. Mistakes to avoid: a mismatch you didn't expect usually raises a ValueError, which is good. The dangerous case is a mismatch that does broadcast: a list of one discount rate silently applies to every line, and a 3 × 3 grid minus three per-row values subtracts them per column unless you make them a column with [:, None]. Check lengths yourself when the data must line up.

Review
  • Arithmetic on arrays is element by element; a single number is used with every value.
  • Broadcasting rule: line shapes up from the right; sizes must match or be 1.
  • values[:, None] makes a column so per-row values apply across each row.
  • Next: replace if/else loops with whole-array rules: np.where, combined masks and running totals.
Practise this

Loading your progress…

To master this lesson, solve both challenges without hints or the answer, and pass the concept check.

Broadcasting — NumPy Foundations · Runtime