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 median() (and other reductions validating axis) when abs(axis) >= self.ndim. A 1-D DatetimeLike array has ndim==1, so axis=1 or axis=2 is out of range; the error protects nanmedian from receiving an invalid axis.

Source

Thrown at pandas/core/arrays/datetimelike.py:1592

        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 71959b8cb9)

Solutions

  1. Pass axis=0 (or axis=None) for 1-D datetimelike arrays.
  2. Check arr.ndim before forwarding an axis argument.
  3. If operating on a DataFrame, call .median(axis=1) on the frame, not on an extracted Index.
  4. Clamp axis to the valid range: axis = None if abs(axis) >= arr.ndim else axis.

Example fix

// before
m = datetime_idx.median(axis=1)  # ValueError: abs(axis) must be less than ndim
// after
m = datetime_idx.median(axis=0)
Defensive patterns

Strategy: validation

Validate before calling

if axis is not None and abs(axis) >= idx.ndim:
    axis = 0
out = idx.median(axis=axis)

Type guard

def valid_axis(idx, axis) -> bool:
    return axis is None or abs(axis) < idx.ndim

Try / catch

try:
    out = idx.median(axis=axis)
except ValueError as e:
    if 'abs(axis) must be less than ndim' in str(e):
        out = idx.median(axis=0)
    else:
        raise

Prevention

When it happens

Trigger: Calling idx.median(axis=1) on a 1-D DatetimeIndex/TimedeltaIndex/PeriodIndex, or passing an axis from a config that assumed 2-D. Reached via the check at line 1591.

Common situations: Reusable reduction helpers that pass axis through generically; DataFrame-vs-Series axis confusion; code that worked on a DataFrame but is reused on an Index.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/1fe9bb3563fe85e0. Report an issue: GitHub.