The vectorisation mindset
What it is
Express the computation as operations on whole arrays. Every Python-level iteration over elements — a for, a comprehension, map — pays interpreter overhead per element; a ufunc pays it once.
Why it matters
The gap is one to two orders of magnitude, and it is the single reason NumPy exists. An interview answer that loops over rows is usually the answer that gets asked to try again.
In the real world: Rewriting a nightly scoring loop as array operations took it from 2 hours to 2 minutes, so results are ready before the business day starts.
# loop: one Python call per element
out = np.array([x * 2 + 1 for x in arr])
# vectorised: one compiled pass
out = arr * 2 + 1
# the same for conditionals
out = np.where(arr > 0, arr, 0.0)Believing the loop is fine because the array is small. It usually is — the problem is that the small array becomes a batch, and the loop is by then three layers down inside a training step.
Practise it: A Confusion Matrix in One Pass, Class Weights From Label Counts, Cosine Similarity Without Loops, One-Hot Encode a Label Vector, Running Share of a Total, Group Sums Without a GroupBy, Intersection Over Union for Every Box Pair, Moving Average Without a Loop, Softmax That Does Not Overflow, Top-K Retrieval Without Sorting Everything, Fill the Gaps in Every Row