{"record":{"id":"c792e6c47b1363c8","repo":"pandas-dev/pandas","slug":"axis-must-be-fewer-than-the-number-of-dimensions","errorCode":null,"errorMessage":"`axis` must be fewer than the number of dimensions ({ndim})","messagePattern":"`axis` must be fewer than the number of dimensions \\((.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/compat/numpy/function.py","lineNumber":363,"sourceCode":"\ndef validate_minmax_axis(axis: AxisInt | None, ndim: int = 1) -> None:\n    \"\"\"\n    Ensure that the axis argument passed to min, max, argmin, or argmax is zero\n    or None, as otherwise it will be incorrectly ignored.\n\n    Parameters\n    ----------\n    axis : int or None\n    ndim : int, default 1\n\n    Raises\n    ------\n    ValueError\n    \"\"\"\n    if axis is None:\n        return\n    if axis >= ndim or (axis < 0 and ndim + axis < 0):\n        raise ValueError(f\"`axis` must be fewer than the number of dimensions ({ndim})\")\n\n\n_validation_funcs = {\n    \"median\": validate_median,\n    \"mean\": validate_mean,\n    \"min\": validate_min,\n    \"max\": validate_max,\n    \"sum\": validate_sum,\n    \"prod\": validate_prod,\n}\n\n\ndef validate_func(fname: str, args: tuple[Any, ...], kwargs: dict[str, Any]) -> None:\n    if fname not in _validation_funcs:\n        return validate_stat_func(args, kwargs, fname=fname)\n\n    validation_func = _validation_funcs[fname]\n    return validation_func(args, kwargs)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/compat/numpy/function.py#L345-L381","documentation":"Raised by validate_minmax_axis, which guards the axis argument of min/max/argmin/argmax (and the corresponding Series/Index/array methods). For 1-D objects (Series, Index) the only legal axis values are 0 or None; anything else means the operation cannot be mapped to a dimension. The check fires when axis >= ndim or when a negative axis still underflows once wrapped.","triggerScenarios":"Calling .min(axis=1)/.max(axis=1)/.argmin(axis=1)/.argmax(axis=1) on a Series or Index (ndim==1); passing axis=2 to a DataFrame-level min/max through the compat dispatcher; passing a negative axis like axis=-2 to a 1-D Series.","commonSituations":"Generic helper code that forwards an axis parameter from a DataFrame to a Series without narrowing it; calling Series.min(axis=df._get_axis_number('columns')); refactors that pass axis=1 down to a per-column Series reduction.","solutions":["Drop or default the axis argument to 0/None when operating on a Series or Index.","Call the reduction on the DataFrame (df.max(axis=1)) rather than forwarding axis to a Series.","Validate the axis against obj.ndim before calling .min/.max on it."],"exampleFix":"# before\ns = pd.Series([1, 2, 3])\ns.max(axis=1)\n# after\ns.max(axis=0)  # or simply s.max()","handlingStrategy":"validation","validationCode":"def safe_reduce(obj, axis=0, how='max'):\n    from pandas.api.types import is_scalar\n    ndim = getattr(obj, 'ndim', 1)\n    if axis is not None and (axis >= ndim or (axis < 0 and ndim + axis < 0)):\n        raise ValueError(f'axis {axis} invalid for ndim={ndim}; defaulting to 0')\n    return getattr(obj, how)(axis=axis if axis is not None else 0)","typeGuard":"def valid_axis_for(obj, axis) -> bool:\n    ndim = getattr(obj, 'ndim', 1)\n    return axis is None or (0 <= axis < ndim) or (-ndim <= axis < 0)","tryCatchPattern":null,"preventionTips":["Default axis to 0/None when reducing a Series or Index.","Forward axis only after checking it against obj.ndim.","Run DataFrame-level reductions rather than looping Series with an axis param."],"tags":["axis","validation","series","reduction"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}