NumPy·Lesson 15·10 min·0/3 exercises

Aggregation and the axis argument

The axis you name is the axis that disappears.

.sum.mean.maxaxis=keepdims.argmax.cumsum

Watch it happen

Play it through, or step back and forth yourself.

DelhiMumbaiPune
MonTueWedThu
cups
120
80
95
150
60
110
90
140
70
130
100
85
shape (4, 3)

cups is (4, 3) — four days down, three stalls across. Two obvious questions: how did each stall do, and how did each day go?

The idea

cups.sum() with no arguments adds up everything and gives you one number. The interesting question is what happens when you only want to collapse part of the array — and that's what axis= is for.

Nearly everyone learns axis=0 as "rows" and axis=1 as "columns", gets it backwards half the time, and never quite trusts it. The reliable reading is different:

The axis you name is the axis that disappears.

cups is (4, 3) — four days by three stalls. cups.sum(axis=0) removes axis 0, so the days are gone and you're left with (3,): one total per stall. cups.sum(axis=1) removes axis 1, so the stalls are gone and you get (4,): one total per day.

Check it against the shape every time and you'll never guess again.

Hand-drawn notes showing that summing along axis zero collapses the rows into one row per column, while axis one collapses the columns, and the axis named is the one that disappears.

keepdims

Sometimes you want the axis collapsed but not removed — usually so the result still broadcasts against the original:

cups.sum(axis=1)                  # (4,)   — flat
cups.sum(axis=1, keepdims=True)   # (4, 1) — still 2-D
cups / cups.sum(axis=1, keepdims=True)   # each row as fractions

Without keepdims that last line fails: a (4,) lines up against the last axis of (4, 3), which is 3, and 4 ≠ 3. With it, you get (4, 1), which stretches perfectly. This is where lesson 5 starts paying rent.

Hand-drawn notes showing keepdims leaving a length-one axis in place so the result still broadcasts back against the original grid.

The rest of the family

They all take axis and behave the same way: mean, min, max, std, var, prod, any, all.

argmax and argmin are worth knowing separately — they return the position of the largest value rather than the value:

cups.max(axis=0)      # the biggest number per stall
cups.argmax(axis=0)   # which day it happened on

And cumsum is the odd one out: it accumulates rather than collapsing, so the shape stays the same. Handy for running totals.

One practical note — if your data has NaN, ordinary sum and mean return NaN. The nan-prefixed versions (np.nansum, np.nanmean) skip them instead.

Practice

Write it yourself. The answer is there when you want it.

Putting the kettle on…

Starting up…

Write it yourself

not graded

Print cups, then its grand total, then the sums along axis=0 and axis=1 — label each with the shape it produces. Print cups.argmax(axis=0), the best day for each stall. Finish with the shape of cups.sum(axis=1, keepdims=True).

Write something and press Run — the output appears here.

Your turn

3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.

Average cups per stall — one number per column.

your answer

The best single stall result on each day — one number per row.

your answer

Turn each row of cups into fractions of that day's total, so every row sums to 1.

your answer