{"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":1601,"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":1583,"sourceCodeEnd":1619,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimelike.py#L1583-L1619","documentation":"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.","triggerScenarios":"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.","commonSituations":"Generic reduction code that passes axis=1 unconditionally; refactoring a DataFrame reduction into an Index/Array reduction without dropping the axis kwarg.","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."],"exampleFix":"// before\ndta.median(axis=1)  # ValueError (1-D array)\n\n// after\ndta.median(axis=0)  # or simply dta.median()","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef median_safe(arr, axis=None):\n    if axis is not None and abs(axis) >= arr.ndim:\n        raise ValueError(f'abs(axis) must be < ndim={arr.ndim}')\n    return arr.median(axis=axis)","typeGuard":null,"tryCatchPattern":"try:\n    return arr.median(axis=axis)\nexcept ValueError as e:\n    if 'abs(axis)' in str(e):\n        return arr.median(axis=0)\n    raise","preventionTips":["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."],"tags":["datetime","reduction","axis","value-error","median"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}