{"record":{"id":"1fe9bb3563fe85e0","repo":"pandas-dev/pandas","slug":"abs-axis-must-be-less-than-ndim","errorCode":null,"errorMessage":"abs(axis) must be less than ndim","messagePattern":"abs\\(axis\\) must be less than ndim","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimelike.py","lineNumber":1592,"sourceCode":"        if isinstance(self.dtype, PeriodDtype):\n            # See discussion in GH#24757\n            raise TypeError(\n                f\"mean is not implemented for {type(self).__name__} since the \"\n                \"meaning is ambiguous.  An alternative is \"\n                \"obj.to_timestamp(how='start').mean()\"\n            )\n\n        result = nanops.nanmean(\n            self._ndarray, axis=axis, skipna=skipna, mask=self.isna()\n        )\n        return self._wrap_reduction_result(axis, result)\n\n    @_period_dispatch\n    def median(self, *, axis: AxisInt | None = None, skipna: bool = True, **kwargs):\n        nv.validate_median((), kwargs)\n\n        if axis is not None and abs(axis) >= self.ndim:\n            raise ValueError(\"abs(axis) must be less than ndim\")\n\n        result = nanops.nanmedian(self._ndarray, axis=axis, skipna=skipna)\n        return self._wrap_reduction_result(axis, result)\n\n    def _mode(self, dropna: bool = True):\n        mask = None\n        if dropna:\n            mask = self.isna()\n\n        i8modes, _ = algorithms.mode(self.view(\"i8\"), mask=mask)\n        npmodes = i8modes.view(self._ndarray.dtype)\n        npmodes = cast(\"np.ndarray\", npmodes)\n        return self._from_backing_data(npmodes)\n\n    # ------------------------------------------------------------------\n    # GroupBy Methods\n\n    def _groupby_op(","sourceCodeStart":1574,"sourceCodeEnd":1610,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/datetimelike.py#L1574-L1610","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass axis=0 (or axis=None) for 1-D datetimelike arrays.","Check arr.ndim before forwarding an axis argument.","If operating on a DataFrame, call .median(axis=1) on the frame, not on an extracted Index.","Clamp axis to the valid range: axis = None if abs(axis) >= arr.ndim else axis."],"exampleFix":"// before\nm = datetime_idx.median(axis=1)  # ValueError: abs(axis) must be less than ndim\n// after\nm = datetime_idx.median(axis=0)","handlingStrategy":"validation","validationCode":"if axis is not None and abs(axis) >= idx.ndim:\n    axis = 0\nout = idx.median(axis=axis)","typeGuard":"def valid_axis(idx, axis) -> bool:\n    return axis is None or abs(axis) < idx.ndim","tryCatchPattern":"try:\n    out = idx.median(axis=axis)\nexcept ValueError as e:\n    if 'abs(axis) must be less than ndim' in str(e):\n        out = idx.median(axis=0)\n    else:\n        raise","preventionTips":["Use axis=0 or axis=None for 1-D Index reductions.","Check arr.ndim before forwarding an axis argument.","Run DataFrame reductions on the frame, not on an extracted Index."],"tags":["axis","median","validation","dimension"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}