numpy.sum() adds array elements. With no arguments beyond the array, it collapses everything into one number. The four settings that decide what you actually get back are axis (which dimensions are collapsed), keepdims (whether those dimensions stay in the result as length one), dtype (the type used for accumulation and the returned value), and the order of operations when you compute a sum of squares. That last one is where most silent errors come from: integer overflow in x ** 2 happens before sum runs, so a wider dtype on the sum cannot repair it.
The signature and the default behavior
The function is documented in the numpy.sum reference for the stable NumPy release labelled v2.5, checked in October 2026. Its signature is:
As an Amazon Associate I earn from qualifying purchases.
numpy.sum(a, axis=None, dtype=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
With the default axis=None, every element is summed and a scalar comes back. Passing an array with axis set changes that: NumPy reduces only the selected dimensions and returns an array with the remaining shape. The parameters out, initial and where are useful but secondary; the rest of this article focuses on the parameters that most often change results.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Choosing an axis
Take the 2 × 3 array x = np.array([[1, 2, 3], [4, 5, 6]]). Its first axis is the row direction (length 2) and its second axis is the column direction (length 3). The axis you pass names the dimension that disappears from the output.
#1 Best Overall
| Call | Dimension reduced | Result | Result shape |
|---|---|---|---|
np.sum(x) |
all | 21 | () |
np.sum(x, axis=0) |
rows, one value per column | [5, 7, 9] | (3,) |
np.sum(x, axis=1) |
columns, one value per row | [6, 15] | (2,) |
np.sum(x, axis=-1) |
last dimension (same as axis=1 here) | [6, 15] | (2,) |
np.sum(x, axis=(0, 1)) |
both dimensions | 21 | () |
The reference’s own example for [[0, 1], [0, 5]] shows the same pattern: axis=0 gives [0, 6] and axis=1 gives [1, 5].
Tuples of axes
A tuple reduces every listed axis at once. On a three-dimensional array with shape (4, 3, 2), np.sum(a, axis=(1, 2)) returns four totals, one per leading index, with shape (4,). Negative values count from the last dimension, so axis=-1 on that array is the same as axis=2.
A common mistake: mixing up the direction
People often expect axis=0 to mean “sum down each column,” which is correct, but then read the output as if it were per row. Print the shape before you use the result: axis=0 on a (2, 3) array gives shape (3,), one value for each column.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorskeepdims: keeping the reduced axis
By default the reduced dimension is removed. Setting keepdims=True leaves it in place with length one, so the result has the same number of dimensions as the input and can broadcast back against it.
| Call on shape (2, 3) | Result shape |
|---|---|
x.sum(axis=1) |
(2,) |
x.sum(axis=1, keepdims=True) |
(2, 1) |
x.sum(axis=0, keepdims=True) |
(1, 3) |
The practical use is normalization. Dividing each row by its own total takes one line:
row_share = x / x.sum(axis=1, keepdims=True)
Without keepdims=True, the division would try to align a length-2 vector against the length-3 columns and either fail or silently compute the wrong thing. Keeping the dimension makes the intent explicit.
dtype: the accumulator and the returned type
The dtype argument controls the type used while summing, and the type of the value returned. It is not a cast applied after the fact. The reference states that by default NumPy uses the input dtype, except that integers narrower than the platform integer are promoted to platform width. Signed inputs use the platform signed integer and unsigned inputs use the platform unsigned integer. On a typical 64-bit Linux build that platform integer is int64.
Recommended Free Tools
import numpy as np
a = np.array([1, 2, 3], dtype=np.int8)
print(np.sum(a).dtype) # int64 on a typical 64-bit Linux build
print(np.sum(a, dtype=np.int8).dtype) # int8
Summing low-precision floats
When you add many float32 values, rounding error can accumulate. Passing dtype=np.float64 uses a wider accumulator and usually reduces that error. The reference adds two caveats: the improvement depends on summing along the fast axis in memory, and exact precision can vary with other parameters. It also notes that math.fsum is slower but more precise. Treat floating-point sums as approximate. Do not write tests that expect bitwise-identical results across different array layouts or reduction orders.
Integer overflow wraps silently
NumPy integer types have fixed sizes and finite ranges, unlike Python’s int, which grows as needed. When a sum exceeds the range of its accumulator, the value wraps around and no exception is raised. The reference’s example shows this directly:
Rank #4
np.ones(128, dtype=np.int8).sum(dtype=np.int8) # -128
The true total is 128. In eight-bit two’s complement, 128 wraps to −128. If the largest possible total of your data could exceed the range of the type, choose a wider accumulator before you sum, not after.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Sum of squares: the order of operations
The expression np.sum(x ** 2) looks like one step but is two. NumPy first computes every square using the dtype of x, and only then accumulates those squares. For integer arrays, that means overflow can happen in the squaring stage, where a dtype argument to sum has no effect.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Consider two values, both 100, stored as int8:
x = np.array([100, 100], dtype=np.int8)
np.sum(x ** 2, dtype=np.int64) # 32, wrong
np.sum(x.astype(np.int64) ** 2, dtype=np.int64) # 20000, correct
In the first line, each square is computed in int8, so 10,000 wraps to 16 before the sum sees it. In the second, the values are widened first, so each square is 10,000 and the total is 20,000.
Best Value
To compute a sum of squares safely for integer input:
- Find the largest value in the array and estimate the largest possible total. For
nelements each bounded byM, the total is at mostn × M². - Confirm that both
M²and that total are below the maximum of your target type. For int64 that maximum is 9,223,372,036,854,775,807. - Convert the array to the wider type before squaring:
x.astype(np.int64). - Square the converted array and pass the same wide type as
dtypetonp.sum, for examplenp.sum(x.astype(np.int64) ** 2, dtype=np.int64).
For floating-point input, squaring has no wraparound, but the rounding rules above still apply. Use dtype=np.float64 on the sum when the input is float32 and the number of terms is large.
Troubleshooting checklist
- Unexpected shape: print
result.shape. A missing dimension usually meanskeepdimswas left at its default. - Negative total for values that must be positive: the sum overflowed. Check the dtype of the input and of the squares.
- Sum of squares far too small: the squaring happened in a narrow type. Convert with
astypebefore the**operator. - Result differs slightly between runs or machines: floating-point accumulation order changed. Compare with a tolerance, not exact equality.
The official reference for every parameter is at numpy.sum in the NumPy stable documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




