Broadcasting in NumPy
Learn how NumPy handles operations on arrays of different shapes
Broadcasting in NumPy
What is Broadcasting?
Broadcasting is NumPy's way of performing operations on arrays of different shapes.
Think of it like automatically expanding smaller arrays to match larger ones, without actually copying data.
Why broadcasting is powerful:
- No need to manually resize arrays
- Memory efficient
- Makes code cleaner
- Much faster than loops
Simple Broadcasting
Scalar to Array
import numpy as np
arr = np.array([1, 2, 3, 4])
result = arr + 10
print(result)Output: [11 12 13 14]
What happens: 10 is "broadcast" to [10, 10, 10, 10] automatically.
Operations
import numpy as np
prices = np.array([100, 200, 300])
with_tax = prices * 1.08
print("With tax:", with_tax)
doubled = prices * 2
print("Doubled:", doubled)No need to create [1.08, 1.08, 1.08] or [2, 2, 2]!
1D to 2D Broadcasting
import numpy as np
matrix = np.array([[1, 2, 3], [4, 5, 6]])
row = np.array([10, 20, 30])
result = matrix + row
print(result)Output:
[[11 22 33]
[14 25 36]]
What happens: [10, 20, 30] is broadcast to match matrix shape:
[[10, 20, 30],
[10, 20, 30]]
Column Broadcasting
import numpy as np
matrix = np.array([[1, 2, 3], [4, 5, 6]])
column = np.array([[10], [20]])
result = matrix + column
print(result)Output:
[[11 12 13]
[24 25 26]]
What happens: [[10], [20]] is broadcast across columns.
Broadcasting Rules
NumPy compares shapes from right to left.
Rule 1: Dimensions must be compatible
- Same size, or
- One of them is 1
Examples that work:
(3, 4) and (4,) # OK: 4 matches 4
(3, 4) and (3, 1) # OK: 1 can broadcast
(3, 1) and (1, 4) # OK: both have 1sExamples that fail:
(3, 4) and (3,) # Error: 4 doesn't match 3
(3, 4) and (2, 4) # Error: 3 doesn't match 2Real-World Example
The scenario: Apply different discounts to product categories.
import numpy as np
prices = np.array([[100, 150, 200], [50, 75, 100], [300, 400, 500]])
print("Original prices (3 categories, 3 products each):")
print(prices)
discounts = np.array([[0.1], [0.2], [0.15]])
print("Discounts per category:")
print(discounts)
discount_amounts = prices * discounts
print("Discount amounts:")
print(discount_amounts)
final_prices = prices - discount_amounts
print("Final prices:")
print(final_prices)What broadcasting does: Applies 10 percent discount to row 1, 20 percent to row 2, 15 percent to row 3.
Normalizing Data
Common in machine learning - subtract mean, divide by std.
import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mean = data.mean(axis=0)
std = data.std(axis=0)
print("Mean per column:", mean)
print("Std per column:", std)
normalized = (data - mean) / std
print("Normalized data:")
print(normalized)Broadcasting makes this easy:
- mean shape (3,) broadcasts to (3, 3)
- std shape (3,) broadcasts to (3, 3)
Practice Example
The scenario: Calculate grades with different weights per assignment.
import numpy as np
scores = np.array([[85, 90, 88], [78, 82, 85], [92, 95, 90]])
print("Student scores (rows=students, columns=assignments):")
print(scores)
weights = np.array([0.3, 0.3, 0.4])
print("Assignment weights:", weights)
weighted_scores = scores * weights
print("Weighted scores:")
print(weighted_scores)
final_grades = weighted_scores.sum(axis=1)
print("Final grades:", final_grades)
class_average = scores.mean(axis=0)
print("Class average per assignment:", class_average)
normalized = scores - class_average
print("Scores relative to class average:")
print(normalized)What this demonstrates:
- Multiply each student's scores by weights (broadcasting)
- Sum across assignments for final grade
- Calculate class averages
- Show how each student compares to average (broadcasting)
Adding New Axis
Sometimes you need to reshape for broadcasting.
import numpy as np
arr = np.array([1, 2, 3])
print("Original shape:", arr.shape)
column = arr[:, np.newaxis]
print("As column shape:", column.shape)
print(column)
row = arr[np.newaxis, :]
print("As row shape:", row.shape)
print(row)What np.newaxis does: Adds a dimension of size 1.
When Broadcasting Fails
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([1, 2])
try:
result = arr1 + arr2
except ValueError as e:
print("Error:", e)Error: Shapes (3,) and (2,) not compatible.
Fix: Make shapes compatible.
Memory Efficiency
Broadcasting doesn't copy data.
import numpy as np
big_array = np.ones((1000, 1000))
scalar = 5
result = big_array + scalarWithout broadcasting: Would need to create array of 1 million 5s.
With broadcasting: No extra memory needed. Much faster!
Key Points to Remember
Broadcasting lets you operate on arrays of different shapes without manual resizing.
Scalar operations broadcast automatically: array + 5 works for any array.
Shapes are compatible if they're equal or one is 1, checked right to left.
Common use: normalize data, apply weights, compute statistics.
Use np.newaxis to add dimensions for broadcasting.
Common Mistakes
Mistake 1: Wrong dimension
matrix = np.array([[1, 2, 3], [4, 5, 6]])
arr = np.array([1, 2]) # Wrong size!
matrix + arr # ErrorMistake 2: Forgetting newaxis
arr = np.array([1, 2, 3])
matrix + arr # Works if matrix has 3 columns
matrix + arr[:, np.newaxis] # If you want column broadcastMistake 3: Assuming copy
broadcasted = arr + 5
arr[0] = 99
# Original arr changed, but broadcasted didn'tWhat's Next?
You now understand broadcasting. Next, you'll learn boolean indexing and filtering - powerful techniques for selecting data based on conditions.