The axis Parameter
Use axis=0 and axis=1 to get per-match vs per-player totals from a 2D scores table, plus keepdims and negative axes.
Our squad data is a table: rows are players, columns are matches. "Total runs" is ambiguous here — do you mean each player's season total, each match's team total, or one grand total? The axis parameter is how you tell NumPy which one you want.
Definition
The
axisparameter tells an aggregate function which dimension to collapse. The result has that dimension removed:axis=0collapses the rows (giving one value per column),axis=1collapses the columns (giving one value per row), andaxis=Nonecollapses everything into a single number.
- Collapse — the axis you name disappears from the shape. A
(4, 5)array summed overaxis=0becomes(5,); overaxis=1it becomes(4,). - axis 0 — the first index,
scores[i, :]→ moving down the rows. - axis 1 — the second index,
scores[:, j]→ moving across the columns.
text
axis 1 → (across: match 1 … match 5)
M1 M2 M3 M4 M5
axis 0 Virat [ 72, 45, 88, 31, 64 ] → sum(axis=1) = 300
↓ Rohit [ 56, 0, 74, 88, 32 ] → sum(axis=1) = 250
(down) Hardik [ 45, 32, 0, 67, 18 ] → sum(axis=1) = 162
Shubman [ 33, 61, 45, 0, 77 ] → sum(axis=1) = 216
↓ ↓ ↓ ↓ ↓
sum(axis=0) = 206 138 207 186 191Tip — the memory trick: "axis=0 goes down, axis=1 goes across." Or: the axis you pass is the one that gets squashed. Squash the rows (axis 0) → one answer per column (per match). Squash the columns (axis 1) → one answer per row (per player).
Syntax
python
a.sum(axis=None, keepdims=False)
a.mean(axis=0) # one value per column
a.max(axis=1) # one value per row
a.sum(axis=(0, 1)) # a tuple of axes = reduce several at once
a.sum(axis=-1) # negative axis counts from the end (-1 = last axis)| Parameter | Meaning | Default |
|---|---|---|
axis | None (whole array), an int (0, 1, -1, …) or a tuple of ints | None |
keepdims | if True, the collapsed axis stays in the shape with size 1 | False |
Works for sum, mean, median, min, max, std, var, prod, argmin, argmax, percentile, cumsum and more.
Example — per player vs per match
python
import numpy as np
scores = np.array([
[72, 45, 88, 31, 64], # Virat
[56, 0, 74, 88, 32], # Rohit
[45, 32, 0, 67, 18], # Hardik
[33, 61, 45, 0, 77], # Shubman
])
print("shape:", scores.shape)
print("Grand total :", scores.sum())
print("Per player (axis=1) :", scores.sum(axis=1), scores.sum(axis=1).shape)
print("Per match (axis=0) :", scores.sum(axis=0), scores.sum(axis=0).shape)
print("Best per player :", scores.max(axis=1))
print("Avg per match :", scores.mean(axis=0))text
shape: (4, 5)
Grand total : 928
Per player (axis=1) : [300 250 162 216] (4,)
Per match (axis=0) : [206 138 207 186 191] (5,)
Best per player : [88 88 67 77]
Avg per match : [51.5 34.5 51.75 46.5 47.75]How it works: axis=1 squashes the 5 match columns, leaving one number for each of the 4 players → shape (4,). axis=0 squashes the 4 player rows, leaving one number for each of the 5 matches → shape (5,).
Example — keepdims=True for broadcasting
Say you want each score as a percentage of that player's season total. Dividing a (4, 5) array by a (4,) array fails, because broadcasting lines shapes up from the right (5 vs 4). keepdims=True keeps the result as a (4, 1) column, which broadcasts perfectly:
python
import numpy as np
scores = np.array([
[72, 45, 88, 31, 64],
[56, 0, 74, 88, 32],
[45, 32, 0, 67, 18],
[33, 61, 45, 0, 77],
])
totals = scores.sum(axis=1, keepdims=True)
print("totals shape:", totals.shape)
print(totals)
share = scores / totals * 100
print(share.round(1))
print("each row adds up to:", share.sum(axis=1).round(1))text
totals shape: (4, 1)
[[300]
[250]
[162]
[216]]
[[24. 15. 29.3 10.3 21.3]
[22.4 0. 29.6 35.2 12.8]
[27.8 19.8 0. 41.4 11.1]
[15.3 28.2 20.8 0. 35.6]]
each row adds up to: [100. 100. 100. 100.]How it works: totals is a column (4, 1). Broadcasting stretches it across the 5 columns, so every score is divided by its own player's total. Without keepdims you would need totals[:, np.newaxis] or .reshape(-1, 1).
Example — 3D data and a tuple of axes
Add a third dimension: 2 seasons × 4 players × 5 matches. Now axis=0 means season, axis=1 means player, axis=2 (or -1) means match.
python
import numpy as np
seasons = np.arange(40).reshape(2, 4, 5) # 2 seasons, 4 players, 5 matches
print("shape:", seasons.shape)
print("sum(axis=0) shape :", seasons.sum(axis=0).shape) # combine seasons
print("sum(axis=-1) shape:", seasons.sum(axis=-1).shape) # one total per season per player
print("per player, all seasons & matches:", seasons.sum(axis=(0, 2)))text
shape: (2, 4, 5)
sum(axis=0) shape : (4, 5)
sum(axis=-1) shape: (2, 4)
per player, all seasons & matches: [120 170 220 270]Common mistakes
- ❌ Thinking
axis=0means "per row". ✅axis=0collapses the rows, so you get one value per column. - ❌
scores / scores.sum(axis=1)→ValueError: operands could not be broadcast together with shapes (4,5) (4,). ✅ Usekeepdims=True. - ❌ Passing
axis=2to a 2D array →AxisError: axis 2 is out of bounds for array of dimension 2. ✅ A 2D array only has axes 0 and 1 (or -1, -2). - ❌ Forgetting
axisand getting one grand total when you wanted per-player totals. ✅ Always ask: one number, one per row, or one per column?
Comparison — the three choices on a (4, 5) array
| Call | Collapses | Result shape | Meaning here |
|---|---|---|---|
scores.sum() | everything | () scalar | squad's grand total |
scores.sum(axis=0) | rows | (5,) | total per match |
scores.sum(axis=1) | columns | (4,) | total per player |
scores.sum(axis=1, keepdims=True) | columns | (4, 1) | per player, kept as a column |
Interview tip
Q: For an array of shape (100, 3), what is the shape of a.mean(axis=0)?
A: (3,) — axis 0 (the 100 rows) is collapsed, leaving one mean per column. In data-science terms: if rows are samples and columns are features, axis=0 gives the per-feature mean.
Key points to remember
- axis tells an aggregate which dimension to collapse; that dimension disappears from the result's shape.
- axis=0 collapses rows → one value per column (per match); axis=1 collapses columns → one value per row (per player).
- axis=None (the default) reduces the whole array to a single number.
- keepdims=True keeps the collapsed axis with size 1, so the result broadcasts back against the original.
- Negative axes count from the end: axis=-1 is always the last axis.
- A tuple like axis=(0, 2) reduces several axes at once.
- Asking for an axis that does not exist raises AxisError.
Try it yourself
Per-player and per-match totals
keepdims for percentages
Shapes after reducing each axis
Practice: best batter of each match
Revision Flashcards
Tap a card to flip it and see the answer.
