NumPy without fear
The slow way, and the fast way
Say you want to double four numbers. In plain Python you write a loop:
It works — but you had to spell out a loop just to touch four numbers. Real models do this to millions of numbers, millions of times. Loops like that are far too slow.
Here's the same thing with NumPy:
No loop. The * 2 hit every number at once:
NumPy repeats the 2 across every box — that's broadcasting.
a * 2 — one operation, applied to the whole group
That is the whole idea of this module — and of fast machine learning:
Stop thinking about one number at a time. Think in whole groups.
NumPy is just the tool that lets you. Everything below is a variation on that one move.
An array is a group of numbers
That's an array: a row of numbers NumPy treats as a single thing, so you do math on the whole row in one shot.
Predict before you run: what will a + 10 print? Then run it:
What happened with a + 10: NumPy repeated the 10 across every box. That auto-repeat has a name — broadcasting — but the idea is just "apply it to everything":
NumPy repeats the 10 across every box — that's broadcasting.
Same numbers, different shape
A shape is just the arrangement of the numbers. reshape rearranges the same numbers into a grid — nothing is added or lost:
[1 2 3 4 5 6] → [1 2 3]
[4 5 6]Collapsing a grid: axes
When you sum a grid you pick a direction to collapse. This trips up almost everyone, so look at it before you read the code:
axis=0 — collapse the rows ↓
one number per column
axis=1 — collapse the columns →
one number per row
axis=0→ collapse the rows, leaving one number per column.axis=1→ collapse the columns, leaving one number per row.
The operation that runs the world: the dot product
This is the single most important operation in machine learning. Take two arrays, multiply them pairwise, then add it all up:
↓ multiply pairwise
↓ add them all up
multiply → combine → summarize
That little "multiply → combine → summarize" is the engine room of modern AI. One neuron, linear regression, attention, embeddings, a whole transformer — under the hood they are all dot products, repeated at enormous scale. (What it actually means — why combining inputs with weights is so powerful — is the next module.)
When shapes don't match
NumPy only combines arrays whose shapes fit. Run this — it errors on purpose:
That error isn't a bug — it's NumPy saying "these groups aren't the same size, I can't pair them up." Shape mismatches are the #1 source of bugs in real ML code, so meeting one now is a gift, not a setback.
Play for two minutes
In any cell above, try the weird stuff — that's where intuition sticks:
- decimals and negatives:
a * -0.5 - a bigger array:
np.arange(20) - a reshape that can't work:
a.reshape(3, 3)on six numbers grid.sum(axis=0)vsgrid.sum(axis=1)— predict each before you run
Four things to carry forward
You don't need to memorise syntax. Carry these four ideas:
- Array = many numbers held as one.
- Shape = how they're arranged.
- Axis = the direction you collapse.
- Dot product = combine inputs with weights (multiply → combine → summarize).
Why this matters
Peel back almost any modern AI system and you find the same thing: huge arrays of numbers — multiplied, added, reshaped, and optimised. That's not a metaphor; it's literally what runs inside a neural network or a transformer. You now recognise the core moves. The rest of machine learning is these operations, scaled up and stacked.