np.max() finds the highest array value or one maximum along each selected axis. Choose the axis, mask and missing-value policy carefully so the reported peak represents observed data.
| Parameter | Meaning |
|---|---|
a | Input array or array-like values |
axis=None | All elements by default; an integer or tuple selects reduction axes |
out=None | Destination matching the result shape |
keepdims=False | Retain reduced axes with length one |
initial | Competing starting value; required for masked or empty reductions |
where | Boolean inclusion mask; broadcastable to the input |
max returns the highest value among the included elements. It does not return its position; use argmax when a position is needed. Use fixed values for repeatable practice or generate data with a random Generator.
import numpy as np
import warnings
def sample_array():
return np.array([[6, 3, 2], [7, 2, 2], [6, 2, 9]])
a = sample_array()
print(a)
assert a.shape == (3, 3)Expected output
[[6 3 2]
[7 2 2]
[6 2 9]]With axis=None, max reduces all elements to one value. axis=0 reduces rows, leaving one peak per column; axis=1 reduces columns, leaving one peak per row. See axis reduction.
a = sample_array()
print("Overall:", a.max())
print("Column peaks:", a.max(axis=0))
print("Row peaks:", a.max(axis=1))
assert a.max() == 9
np.testing.assert_array_equal(a.max(axis=0), [7, 3, 9])
np.testing.assert_array_equal(a.max(axis=1), [6, 7, 9])Expected output
Overall: 9
Column peaks: [7 3 9]
Row peaks: [6 7 9]
For shape (3, 4), column maxima have shape (4,) and row maxima shape (3,). Square examples can hide axis confusion. Review array shape.
a = np.arange(12).reshape(3, 4)
print("Column peaks:", a.max(axis=0), a.max(axis=0).shape)
print("Row peaks:", a.max(axis=1), a.max(axis=1).shape)
assert a.max(axis=0).shape == (4,)
assert a.max(axis=1).shape == (3,)Expected output
Column peaks: [ 8 9 10 11] (4,)
Row peaks: [ 3 7 11] (3,)A column reduction needs a destination with one element per column. An overall scalar needs a zero-dimensional destination. Use a compatible dtype so the stored peak retains its meaning. max returns the supplied destination.
a = sample_array()
x = np.zeros(3, dtype=a.dtype)
returned = a.max(axis=0, out=x)
y = np.array(1, dtype=a.dtype)
a.max(out=y)
print("Column destination:", x)
print("Scalar destination:", y)
assert returned is x
np.testing.assert_array_equal(x, [7, 3, 9])
assert y == 9Expected output
Column destination: [7 3 9]
Scalar destination: 9keepdims preserves the number of axes, not their original lengths. Reducing all axes of this 2D array produces shape (1, 1); a row reduction produces (3, 1), suitable for broadcasting across columns.
a = sample_array()
print("Retained overall result:", a.max(keepdims=True))
print("Default scalar:", a.max(keepdims=False))
peaks = a.max(axis=1, keepdims=True)
print("Row peak shape:", peaks.shape)
print("Distance below row peak:")
print(peaks - a)
assert a.max(keepdims=True).shape == (1, 1)
assert peaks.shape == (3, 1)Expected output
Retained overall result: [[9]]
Default scalar: 9
Row peak shape: (3, 1)
Distance below row peak:
[[0 3 4]
[0 5 5]
[3 7 0]]The mask [True, False, True] selects the first and third columns in every row because dimensions align from the right. Provide initial for a masked max reduction. This original sample contains 9 in an included column, so its selected overall maximum is 9. See broadcasting.
a = sample_array()
mask = np.array([True, False, True])
print("Selected overall peak:", a.max(where=mask, initial=2))
print("Selected row peaks:", a.max(axis=1, where=mask, initial=2))
print("Selected column peaks:", a.max(axis=0, where=mask, initial=2))
assert a.max(where=mask, initial=2) == 9
np.testing.assert_array_equal(a.max(axis=1, where=mask, initial=2), [6, 7, 9])
np.testing.assert_array_equal(a.max(axis=0, where=mask, initial=2), [7, 2, 9])Expected output
Selected overall peak: 9
Selected row peaks: [6 7 9]
Selected column peaks: [7 2 9]
initial participates in every reduction, even when selected observations exist. A large initial can replace the observed maximum. Choose it no greater than any admissible observation when it is intended only as a sentinel.
a = sample_array()
print("No initial:", a.max())
print("initial=2:", a.max(initial=2))
print("initial=12:", a.max(initial=12))
print("Column peaks with initial=12:", a.max(axis=0, initial=12))
print("Column peaks with initial=2:", a.max(axis=0, initial=2))
assert a.max(initial=12) == 12
np.testing.assert_array_equal(a.max(axis=0, initial=12), [12, 12, 12])Expected output
No initial: 9
initial=2: 9
initial=12: 12
Column peaks with initial=12: [12 12 12]
Column peaks with initial=2: [7 3 9]If all measurements are negative, initial=0 fabricates a higher result than any observation. For floating-point data, -inf can serve as a lower sentinel. For integer data use a validated lower bound, such as the dtype minimum, and track selected counts separately.
a = np.array([-8.0, -3.0, -12.0])
print("Observed maximum:", a.max())
print("initial=0:", a.max(initial=0))
print("Lower sentinel:", a.max(initial=-np.inf))
integers = np.array([-8, -3, -12], dtype=np.int16)
lower = np.iinfo(integers.dtype).min
print("Integer masked max:", integers.max(where=integers < 0, initial=lower))
assert a.max() == -3 and a.max(initial=0) == 0Expected output
Observed maximum: -3.0
initial=0: 0.0
Lower sentinel: -3.0
Integer masked max: -3max on an empty array raises ValueError without initial. A sentinel lets the computation run but does not become an observed peak. Retain selected counts to distinguish a true value equal to the sentinel from no observations.
try:
np.array([], dtype=float).max()
except ValueError:
print("Empty max without initial: ValueError")
else:
raise AssertionError('Expected ValueError')
a = np.array([4.0, 8.0])
mask = np.array([False, False])
peak = a.max(where=mask, initial=-np.inf)
print("Masked sentinel:", peak)
print("Selected count:", mask.sum())
assert peak == -np.inf and mask.sum() == 0Expected output
Empty max without initial: ValueError
Masked sentinel: -inf
Selected count: 0Choose max if an unknown value should make the peak unknown. nanmax gives the maximum of observed non-NaN values, while an all-NaN slice returns NaN with a warning. nanmax still includes infinity.
a = np.array([2.0, np.nan, 9.0])
print("max:", a.max())
print("nanmax:", np.nanmax(a))
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter('always', RuntimeWarning)
unknown = np.nanmax([np.nan, np.nan])
print("All missing:", unknown)
assert np.isnan(a.max()) and np.nanmax(a) == 9
assert np.isnan(unknown) and caughtExpected output
max: nan
nanmax: 9.0
All missing: nanIf infinity is invalid for your measurements, explicitly select finite values. Convert no-observation results to NaN for reporting. A known zero and a missing peak remain different outcomes. See NaN and dtypes.
a = np.array([[2.0, np.nan, 9.0], [np.nan, np.inf, np.nan], [0.0, 0.0, 0.0]])
valid = np.isfinite(a)
counts = valid.sum(axis=1)
peaks = a.max(axis=1, where=valid, initial=-np.inf)
report = np.where(counts > 0, peaks, np.nan)
print("Finite counts:", counts)
print("Reported peaks:", report)
np.testing.assert_allclose(report, [9, np.nan, 0], equal_nan=True)Expected output
Finite counts: [2 0 3]
Reported peaks: [ 9. nan 0.]argmax returns a positional index and chooses the first occurrence of a tie. It does not return a label or all peak positions. Here the data is finite; handle missing values separately before searching for positions.
a = np.array([[4, 9, 9], [7, 2, 7]])
first = a.argmax(axis=1)
peaks = a.max(axis=1, keepdims=True)
ties = a == peaks
print("First peak columns:", first)
print("Peak values:", np.take_along_axis(a, first[:, None], axis=1).ravel())
print("All tied positions:")
print(np.argwhere(ties))
np.testing.assert_array_equal(first, [1, 0])
assert ties.sum() == 4Expected output
First peak columns: [1 0]
Peak values: [9 7]
All tied positions:
[[0 1]
[0 2]
[1 0]
[1 2]]Use max to reduce an array; use maximum to compare corresponding values of two broadcast-compatible arrays. maximum propagates NaN; fmax selects the non-NaN operand when only one is NaN.
a = np.array([2.0, np.nan, 8.0])
b = np.array([5.0, 4.0, np.nan])
print("maximum:", np.maximum(a, b))
print("fmax:", np.fmax(a, b))
np.testing.assert_allclose(np.fmax(a, b), [5, 4, 8])Expected output
maximum: [ 5. nan nan]
fmax: [5. 4. 8.]For shape (2, 3, 4), reducing (0, 2) leaves the middle dimension. keepdims retains those reduced dimensions with size one.
a = np.arange(24).reshape(2, 3, 4)
peaks = a.max(axis=(0, 2))
kept = a.max(axis=(0, 2), keepdims=True)
print("Peaks:", peaks)
print("Retained shape:", kept.shape)
np.testing.assert_array_equal(peaks, [15, 19, 23])
assert kept.shape == (1, 3, 1)Expected output
Peaks: [15 19 23]
Retained shape: (1, 3, 1)This synthetic table has days down rows and Books, Pens and Gifts across columns. Ignore missing measurements for a peak-known report, but include observation counts and coverage. With unknown days, the actual period peak could be higher than the known peak.
sales = np.array([[120.0, 30.0, 0.0], [80.0, np.nan, 20.0],
[100.0, 40.0, 10.0], [np.nan, np.nan, np.nan]])
valid = np.isfinite(sales)
counts = valid.sum(axis=0)
peaks = sales.max(axis=0, where=valid, initial=-np.inf)
report = np.where(counts > 0, peaks, np.nan)
print("Books / Pens / Gifts known peaks:", report)
print("Observed days:", counts)
print("Coverage:", counts / sales.shape[0])
np.testing.assert_allclose(report, [120, 40, 20])
np.testing.assert_array_equal(counts, [3, 2, 3])Expected output
Books / Pens / Gifts known peaks: [120. 40. 20.]
Observed days: [3 2 3]
Coverage: [0.75 0.5 0.75]The largest individual product entry is different from the largest daily total. Sum only complete days for a complete-day comparison and report how many days qualify. See sum().
sales = np.array([[120.0, 30.0, 0.0], [80.0, np.nan, 20.0],
[100.0, 40.0, 10.0], [np.nan, np.nan, np.nan]])
complete = np.isfinite(sales).all(axis=1)
totals = sales[complete].sum(axis=1)
peak = totals.max() if totals.size else np.nan
print("Complete-day totals:", totals)
print("Peak complete-day total:", peak)
print("Complete days:", complete.sum())
assert peak == 150 and complete.sum() == 2Expected output
Complete-day totals: [150. 150.]
Peak complete-day total: 150.0
Complete days: 2max has no dtype argument; inspect input and output dtypes instead. keepdims retains reduced axes with length one. Masks follow broadcasting rules, so a (columns,) mask selects columns rather than rows. initial competes with observed values. Missing-group sentinels are not real peaks. argmax returns a first positional index, not all tied records. Compare min(), mean() and where() for related operations.
Include Books and Gifts from the sales matrix and exclude Pens. Ignore nonfinite values and retain NaN for a day with no included observations. Predict peaks [120, 80, 100, NaN] and counts [2, 2, 2, 0].
Combine the selected-product mask with the finite-value mask, reduce across columns and use counts to identify unknown days.
sales = np.array([[120.0, 30.0, 0.0], [80.0, np.nan, 20.0],
[100.0, 40.0, 10.0], [np.nan, np.nan, np.nan]])
products = np.array([True, False, True])
include = products & np.isfinite(sales)
counts = include.sum(axis=1)
peaks = sales.max(axis=1, where=include, initial=-np.inf)
report = np.where(counts > 0, peaks, np.nan)
print("Included-product peaks:", report)
print("Included counts:", counts)
np.testing.assert_allclose(report, [120, 80, 100, np.nan], equal_nan=True)
np.testing.assert_array_equal(counts, [2, 2, 2, 0])Expected output
Included-product peaks: [120. 80. 100. nan]
Included counts: [2 2 2 0]Open in Google Colab View on GitHub
All sample data is embedded. Run the examples and practise axes, masked peaks and sales reporting. Save a copy in Drive to keep your changes.
Continue with NumPy tutorials, axis reduction, mean() and sum(). Reference: NumPy max documentation.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.