The axis Parameter Explained
Reviewed & published by Brayan K
The axis parameter tells a NumPy function which dimension to operate along and collapse — axis=0 works down the rows to give a result per column, while axis=1 works across the columns to give a result per row.
Part of the free NumPy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll build a reliable mental model using sum and mean on 2D arrays, learn the one rule that ends the confusion forever, and see how keepdims keeps shapes broadcast-friendly.
What You'll Learn in This Lesson
- What axis really means: the dimension that disappears
- axis=0 collapses rows to give per-column results
- axis=1 collapses columns to give per-row results
- Applying axis to sum, mean, max and more
- Keeping shape with keepdims=True
- Why the no-axis call returns one scalar
1 The One Rule: The Named Axis Disappears
Forget "rows" and "columns" for a moment. The reliable rule is: the axis you pass is the one that gets collapsed and removed from the result's shape. A (3, 4) array reduced along axis=0 loses the 3 and becomes shape (4,); reduced along axis=1 it loses the 4 and becomes shape (3,).
import numpy as np
a = np.arange(12).reshape(3, 4) # shape (3, 4)
a.sum(axis=0).shape # (4,) -> the 3 collapsed
a.sum(axis=1).shape # (3,) -> the 4 collapsedimport numpy as np
a = np.array([[1, 2, 3],
[4, 5, 6]]) # shape (2, 3)
# axis=0 -> collapse the 2 rows -> one total per column
print(a.sum(axis=0)) # [5 7 9]
print(a.sum(axis=0).shape) # (3,)
# axis=1 -> collapse the 3 columns -> one total per row
print(a.sum(axis=1)) # [ 6 15]
print(a.sum(axis=1).shape) # (2,)
# ✅ Expected output:
# [5 7 9]
# (3,)
# [ 6 15]
# (2,)2 axis=0 vs axis=1 in Practice
The same idea works for every reduction — mean, max, min, std, and more. Think of a small grades table where rows are students and columns are subjects: axis=0 gives the class average per subject, while axis=1 gives each student's average across subjects.
grades = np.array([[80, 90, 100],
[60, 70, 80]])
# rows = students, columns = subjects
grades.mean(axis=0) # per-subject average: [70. 80. 90.]
grades.mean(axis=1) # per-student average: [90. 70.]import numpy as np
grades = np.array([[80, 90, 100],
[60, 70, 80]])
# Per-subject average (collapse students)
print(grades.mean(axis=0)) # [70. 80. 90.]
# Per-student average (collapse subjects)
print(grades.mean(axis=1)) # [90. 70.]
# Highest score in each subject
print(grades.max(axis=0)) # [ 80 90 100]
# ✅ Expected output:
# [70. 80. 90.]
# [90. 70.]
# [ 80 90 100]3 keepdims=True for Broadcast-Friendly Shapes
Normally a reduction removes the axis entirely, dropping a dimension. Passing keepdims=True keeps that axis with size 1, so the result lines up perfectly for broadcasting back onto the original array — the standard way to subtract per-row or per-column means.
a = np.arange(12).reshape(3, 4)
a.sum(axis=1).shape # (3,) -> dimension dropped
a.sum(axis=1, keepdims=True).shape # (3, 1) -> dimension kept
# (3, 1) broadcasts cleanly against (3, 4):
a - a.mean(axis=1, keepdims=True)import numpy as np
a = np.array([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]]) # shape (2, 3)
row_means = a.mean(axis=1, keepdims=True)
print(row_means.shape) # (2, 1)
print(row_means)
# [[2.]
# [5.]]
# Subtract each row's mean from that row (broadcasting)
print(a - row_means)
# [[-1. 0. 1.]
# [-1. 0. 1.]]
# ✅ Expected output:
# (2, 1)
# [[2.]
# [5.]]
# [[-1. 0. 1.]
# [-1. 0. 1.]]🎯 YOUR TURN: Fill in the Blank
Replace ___ with the correct axis number so you get one total per column.
import numpy as np
sales = np.array([[10, 20, 30],
[40, 50, 60]]) # rows = days, cols = products
# 🎯 YOUR TURN:
# Get the TOTAL sales for each PRODUCT (one number per column).
# Hint: to get a result per column, collapse the rows.
totals = sales.sum(axis=___)
print(totals)
# Expected output:
# [50 70 90]Answer: 0 — collapsing axis 0 (the rows) leaves one total per column.
! Common Errors (And How to Fix Them)
❌ Reading axis=0 as "sum the rows"
It collapses the row dimension, giving a per-column result:
# a = [[1, 2], [3, 4]]
a.sum(axis=0) # [4 6] (per column), NOT [3, 7]✅ Fix: say "the named axis disappears" — axis=0 leaves a result per column.
❌ "operands could not be broadcast" after a reduction
a - a.mean(axis=1) # ❌ (3,4) vs (3,) shapes clash✅ Fix: add keepdims=True so the result is (3, 1) and broadcasts.
❌ "axis 2 is out of bounds"
A 2D array only has axes 0 and 1.
✅ Fix: check arr.ndim; valid axes run from 0 to ndim − 1.
🎯 Mini Challenge: Summarize a Table
Given a temperatures table (rows = cities, columns = days), find the warmest day overall per city and the average temperature per day across cities.
import numpy as np
temps = np.array([[15, 18, 21], # city A
[10, 12, 14], # city B
[20, 22, 19]]) # city C
# Warmest day for each city (collapse the days -> per row)
print(temps.max(axis=1)) # [21 14 22]
# Average temperature each day across cities (collapse cities -> per column)
print(temps.mean(axis=0)) # [15. 17.33333333 18.]
# Grand average over everything (no axis)
print(round(temps.mean(), 2)) # 16.78
# ✅ Expected output:
# [21 14 22]
# [15. 17.33333333 18. ]
# 16.78❓ Frequently Asked Questions
Lesson complete — axis confusion solved!
You now know that the axis you name is the one that collapses: axis=0 gives per-column results, axis=1 gives per-row results, and keepdims=True keeps shapes broadcast-ready.
Practice quiz
What is the one reliable rule about the axis you pass to a reduction?
- It is the axis you keep
- It is always the rows
- It is the axis that gets collapsed and removed
- It must be 1 for 2D arrays
Answer: It is the axis that gets collapsed and removed. The named axis disappears from the result's shape.
A (3, 4) array reduced along axis=0 becomes which shape?
- (3,)
- (4,)
- (3, 4)
- (1, 4)
Answer: (4,). axis=0 loses the 3, leaving shape (4,).
A (3, 4) array reduced along axis=1 becomes which shape?
- (3,)
- (4,)
- (3, 4)
- (1, 3)
Answer: (3,). axis=1 loses the 4, leaving shape (3,).
For grades = [[80,90,100],[60,70,80]], what is grades.mean(axis=0)?
- [90. 70.]
- 75.
- [80. 90. 100.]
- [70. 80. 90.]
Answer: [70. 80. 90.]. axis=0 collapses the students, giving the per-subject averages [70. 80. 90.].
For grades = [[80,90,100],[60,70,80]], what is grades.mean(axis=1)?
- [70. 80. 90.]
- [90. 70.]
- 80.
- [80. 60.]
Answer: [90. 70.]. axis=1 collapses the subjects, giving each student's average: 90 and 70.
What does keepdims=True do during a reduction?
- Doubles the result
- Removes one extra axis
- Keeps the reduced axis with size 1
- Returns a scalar
Answer: Keeps the reduced axis with size 1. keepdims=True keeps the collapsed axis as size 1 for easy broadcasting.
For grades = [[80,90,100],[60,70,80]], what is grades.max(axis=0)?
- [80 90 100]
- 100
- [100 80]
- [90 70]
Answer: [80 90 100]. axis=0 collapses rows, giving the highest score in each subject column.
Which call returns a single scalar over the entire array?
- arr.sum(axis=0)
- arr.sum(axis=1)
- arr.sum(keepdims=True)
- arr.sum()
Answer: arr.sum(). With no axis, the reduction runs over the whole flattened array.
A (3, 4) array reduced along axis=1 with keepdims=True becomes which shape?
- (3,)
- (3, 1)
- (1, 4)
- (4,)
Answer: (3, 1). keepdims keeps the collapsed axis at size 1, giving (3, 1).
Reading axis=0 as 'sum the rows you see' is wrong because...
- axis=0 errors on 2D arrays
- it sums diagonals
- it actually gives a per-column result
- it returns a scalar
Answer: it actually gives a per-column result. axis=0 collapses the row dimension, producing one value per column.
Continue this course
- Previous: Splitting Arrays: split, hsplit & vsplit
- Next: Fancy Indexing with Integer Arrays — Select and reorder elements with arrays of integer indices
- Quick reference: NumPy cheat sheet
Frequently asked questions
What does axis=0 mean versus axis=1?
axis=0 runs DOWN the rows, collapsing the row dimension so you get one result per column. axis=1 runs ACROSS the columns, collapsing the column dimension so you get one result per row. The simplest rule: the axis you name is the one that disappears from the result's shape.
Why do my axis results come out with the wrong orientation?
It is almost always a mix-up between 'the axis you reduce over' and 'the axis you keep'. sum(axis=0) does NOT mean 'sum the rows' — it means 'collapse axis 0', which produces a per-column total. Picture the dimension being squashed flat: whatever index you pass is the one that is removed.
What does keepdims=True do?
Normally a reduction removes the axis you operate on, lowering the number of dimensions. keepdims=True keeps that axis with size 1 instead, so a (3, 4) array reduced along axis=1 becomes (3, 1) rather than (3,). That shape is perfect for broadcasting the result back against the original array, for example to subtract per-row means.
If I do not pass axis at all, what happens?
Without an axis argument, the reduction is applied over the entire flattened array, returning a single scalar. arr.sum() adds every element regardless of shape. Pass axis only when you want a result per row or per column instead of one grand total.