pandas-dev/pandas · error · ValueError
abs(axis) must be less than ndim
Error message
abs(axis) must be less than ndim
What it means
Raised by DatetimeLikeArrayMixin.median (the AxisInt validation) when abs(axis) >= self.ndim. DatetimeLikeArrayMixin is 1-D, so any axis other than 0 (or -1 in 1-D, which equals 0) is out of range; the guard runs before nanops.nanmedian is called.
Solutions
- Pass axis=0 (or None) for 1-D datetimelike arrays.
- Drop the axis argument entirely — median() defaults to the only valid axis.
- If operating on a DataFrame, call .median(axis=1) on the DataFrame, not on an extracted 1-D array.
Example fix
// before dta.median(axis=1) # ValueError (1-D array) // after dta.median(axis=0) # or simply dta.median()
Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def median_safe(arr, axis=None):
if axis is not None and abs(axis) >= arr.ndim:
raise ValueError(f'abs(axis) must be < ndim={arr.ndim}')
return arr.median(axis=axis) Try / catch
try:
return arr.median(axis=axis)
except ValueError as e:
if 'abs(axis)' in str(e):
return arr.median(axis=0)
raise Prevention
- Pass axis=0 or None for 1-D datetimelike arrays.
- Omit axis for single-array reductions.
- Run .median(axis=...) on DataFrames, not on extracted 1-D arrays.
When it happens
Trigger: Calling DatetimeIndex.median(axis=1) on a 1-D index; TimedeltaArray.median(axis=2); passing an axis argument intended for a DataFrame down to a 1-D array reduction.
Common situations: Generic reduction code that passes axis=1 unconditionally; refactoring a DataFrame reduction into an Index/Array reduction without dropping the axis kwarg.
Related errors
- cannot add indices of unequal length
- Cannot modify read-only array
- datetime64 type does not support operation
- mean is not implemented for
- Accumulation not supported for
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/1fe9bb3563fe85e0.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimelike.py:1601
if isinstance(self.dtype, PeriodDtype):
# See discussion in GH#24757
raise TypeError(
f"mean is not implemented for {type(self).__name__} since the "
"meaning is ambiguous. An alternative is "
"obj.to_timestamp(how='start').mean()"
)
result = nanops.nanmean(
self._ndarray, axis=axis, skipna=skipna, mask=self.isna()
)
return self._wrap_reduction_result(axis, result)
@_period_dispatch
def median(self, *, axis: AxisInt | None = None, skipna: bool = True, **kwargs):
nv.validate_median((), kwargs)
if axis is not None and abs(axis) >= self.ndim:
raise ValueError("abs(axis) must be less than ndim")
result = nanops.nanmedian(self._ndarray, axis=axis, skipna=skipna)
return self._wrap_reduction_result(axis, result)
def _mode(self, dropna: bool = True):
mask = None
if dropna:
mask = self.isna()
i8modes, _ = algorithms.mode(self.view("i8"), mask=mask)
npmodes = i8modes.view(self._ndarray.dtype)
npmodes = cast("np.ndarray", npmodes)
return self._from_backing_data(npmodes)
# ------------------------------------------------------------------
# GroupBy Methods
def _groupby_op(View on GitHub (pinned to 3b7651241d)