Work these before Sep 15. For every problem, write down your answer before running the cell. Getting it right after seeing the output teaches you nothing; being wrong and understanding why is the entire point.
The first eight problems are for discussion and have no automatic marking. The graded problems at the end check themselves.
Shapes
Give the shape of each result without running anything, then check.
reshape(-1, 3) and reshape(3, -1) both work on a 12-element array and give different answers. Predict both, then explain in one sentence what -1 means.
Broadcasting
Standardise X so that every column has mean 0 and standard deviation 1. Then do the same for every row. One of the two needs keepdims=True; say which and why.
Compute the matrix of pairwise absolute differences between all entries of v, using broadcasting and no loop. The result should be 6\times 6.
Views and copies
Predict what A looks like after each of the two blocks below. They differ by one method call and the difference matters.
Basic slicing returns a view; fancy indexing returns a copy. Demonstrate the difference in two cells, and state the practical consequence for a function that takes an array and modifies it.
Finding the bug
This is meant to replace every negative value with 0, leaving A unchanged. It does not. Two separate things are wrong. Find both.
This runs, produces numbers, and is wrong. It is supposed to give the mean of each row.
Say precisely what quantity it does compute, and why it does not even have the right shape.
Both lines below run. One of them is a trap that only fails on non-square data. Identify it, and explain why testing on a 4\times 4 array would not have caught the bug.
Then change the shape to (6, 4) and run both again.
np.where is not an if. Explain why the first line below emits a warning while the second does not, even though they return identical numbers.
Graded problems
These check themselves. Reason your way to the answer rather than guessing at the blank—the feedback is written to tell you which misconception you hit.
Build the 6\times 6 matrix whose (i, j) entry is |v_i - v_j|, using broadcasting and no loop.
The diagonal should be zero, and the matrix should be symmetric—two free checks on your answer.
answer = np.abs(v[:, np.newaxis] - v)
Shapes (6, 1) and (6,) right-align as (6, 1) against (1, 6); both length-1 axes stretch and you get all 36 pairs.
X has 6 observations in rows and 3 features in columns, on wildly different scales. Standardise it so that every column has mean 0 and standard deviation 1.
This is the first step of PCA, and getting the axis wrong here is the most expensive mistake in the module.
Z = (X - X.mean(axis=0)) / X.std(axis=0)
No keepdims is needed, because a (3,) result already right-aligns correctly against (6, 3). Standardising the rows would need keepdims=True on both reductions.
Problem 8’s line runs and returns a number, but it is neither the right value nor the right shape. Replace it with an expression giving the mean of each row—a result of shape (3,).
row_means = A.mean(axis=1)
The original bug was twofold: A.sum() with no axis flattens the whole array, and dividing by A.shape[1] then gives 5 times the grand mean rather than anything meaningful.
For each column of X, count how many of its entries exceed that column’s own mean. The answer is an array of 4 integers.
You will need one reduction to get the means, a comparison that broadcasts, and a second reduction to count. Watch the shapes at each step.
answer = (X > X.mean(axis=0)).sum(axis=0)
Three moves: reduce to (4,) means, broadcast the comparison back up to a (10, 4) boolean mask, then reduce that mask over axis=0. Summing booleans counts them, because True is 1.
T has shape (2, 3, 4) and holds non-negative weights. Rescale it so that the four values along the last axis sum to 1 for every one of the 6 combinations of the first two axes.
The result must keep shape (2, 3, 4).
answer = T / T.sum(axis=-1, keepdims=True)
axis=-1 always names the last axis, whatever the order of the array, which makes it more robust than hard-coding axis=2. Without keepdims=True the divisor would have shape (2, 3), which right-aligns 3 against 4 and raises a ValueError.
Going further
For extra drill, 100 NumPy exercises is a well-known problem set. Work them with the documentation open and an AI assistant closed; the value is in the reasoning, and both of those choices matter.