Sample questions
Aipy Numpy Vectorization BroadcastingDifficulty 1
In NumPy broadcasting, two dimensions are compared starting from which end of the shape tuples?
- aFrom the trailing (rightmost) end; missing leading dimensions are treated as size 1.✓
- bFrom the leading (leftmost) end; missing trailing dimensions are treated as size 1. This reverses the actual comparison direction NumPy uses for shape alignment.
- cFrom the middle outward, comparing the largest dimension first.
- dDimensions are never compared; only total element counts must match.
Explanation:Broadcasting aligns shapes from the trailing dimension and works backward; if one array has fewer dimensions, size-1 dimensions are implicitly prepended. (b) reverses the direction. (c) and (d) describe mechanisms broadcasting does not use.
Aipy Numpy Vectorization BroadcastingDifficulty 1
import numpy as np
a = np.ones((3, 4))
b = np.array([10, 20, 30, 40])
result = a + b
What is
result.shape?
- a(4, 4), because
b is repeated once per its own length. - b(3, 4), because
b's shape (4,) is treated as (1, 4) and broadcast across the 3 rows.✓ - cThis raises a
ValueError, because a and b do not have the same number of dimensions. - d(3,), because
b is reduced to match a's first dimension.
Explanation:b has shape (4,), which aligns with a's trailing dimension (also 4); the missing leading dimension is treated as 1, so b broadcasts to (1, 4) and then stretches across all 3 rows, giving (3, 4). (a) miscomputes the shape. (c) wrongly assumes dimension count must match exactly. (d) describes reduction, not broadcasting.
Aipy Numpy Vectorization BroadcastingDifficulty 2
import numpy as np
a = np.ones((3, 4))
c = np.array([1, 2, 3])
result = a + c
What happens?
- a
c is transposed automatically and broadcasts to (3, 4) as columns. - b
result has shape (3, 4), with c broadcast across the 4 columns. - cThis raises a
ValueError, because the trailing dimensions (4 vs 3) are unequal and neither is 1.✓ - d
result has shape (3, 3), since NumPy trims a to match c's length. This is a plausible-sounding but incorrect description of how NumPy resolves shape mismatches during arithmetic.
Explanation:a has shape (3, 4) and c has shape (3,); comparing trailing dimensions gives 4 vs 3, which are unequal and neither is 1, so broadcasting fails with a ValueError. (a) and (d) describe outcomes broadcasting does not produce; NumPy never auto-transposes or trims arrays to make shapes fit. (b) is the shape that would result only if c had shape (4,), not (3,).
Aipy Numpy Vectorization BroadcastingDifficulty 1
When you add a Python scalar to a NumPy array, e.g. arr + 5, how does broadcasting treat the scalar?
- aIt raises an error unless the scalar is first wrapped in a one-element array with a matching shape.
- bIt is only added to the first element of
arr, leaving the rest unchanged. - cIt is converted into an array whose shape exactly matches
arr's shape by copying arr's dimension sizes ahead of time. - dIt is treated as having a shape of
() (zero dimensions), which broadcasts against every dimension of arr.✓
Explanation:A scalar behaves as a 0-dimensional array; broadcasting treats every one of its (nonexistent) dimensions as size 1, so it stretches to match any shape of arr. (a) and (b) describe restrictions or behavior that don't exist. (c) describes the conceptual result but misstates the mechanism — no explicit array copy of shape happens beforehand.
Aipy Numpy Vectorization BroadcastingDifficulty 1
Why is a vectorized NumPy operation like a + b typically much faster than an equivalent Python for loop over the elements?
- aThe loop over elements runs inside compiled C code, avoiding per-element Python bytecode dispatch and type-checking overhead.✓
- bNumPy automatically runs the operation on multiple CPU cores, while a Python loop is always single-core.
- cNumPy arrays store elements as Python objects with cached results, so repeated operations are free after the first call.
- dThe Python
for loop always allocates a new list on every iteration, which vectorized code skips entirely.
Explanation:NumPy's ufuncs iterate over array data in compiled C loops operating on raw, uniformly-typed memory, avoiding the per-element overhead of the Python interpreter (bytecode dispatch, dynamic type checks, object boxing) that a plain for loop incurs. (b) is not guaranteed — most elementwise ufuncs run single-threaded by default. (c) misdescribes array storage; NumPy stores raw numeric values, not Python objects, and there's no caching mechanism like this. (d) is not the actual reason for the loop's slowness.
Aipy Numpy Vectorization BroadcastingDifficulty 2
import numpy as np
n = 1_000_000
arr = np.arange(n)
def loop_sum_sq():
total = 0
for x in arr:
total += x * x
return total
def vec_sum_sq():
return np.sum(arr * arr)
Both functions compute the same mathematical result. What is the main practical difference?
- a
vec_sum_sq produces a different numeric result due to rounding, since NumPy sums in a random order. - b
loop_sum_sq is far slower because it re-enters the Python interpreter for every one of the million elements; vec_sum_sq does the multiply-and-sum in compiled loops.✓ - c
loop_sum_sq is faster because Python integers avoid NumPy's fixed-width overflow issues entirely. - dThere is no meaningful difference for
n = 1_000_000; both approaches take about the same wall-clock time.
Explanation:Iterating for x in arr yields plain Python objects one at a time and executes the loop body (attribute lookups, multiplication, addition) through the Python interpreter for each of the million elements, which is comparatively slow. vec_sum_sq performs the multiplication and the summation as vectorized C-level operations. (a) is false for integer sums — order doesn't introduce rounding here. (c) is not a real advantage; it's irrelevant to the observed slowdown and NumPy's default integer dtype here has ample range. (d) understates the difference, which is typically substantial (often tens of times or more) at this scale.