{"record":{"id":"4233d6b1e6b45dd7","repo":"pandas-dev/pandas","slug":"cannot-perform-reduction-name-with-string-dtyp-4233d6","errorCode":null,"errorMessage":"Cannot perform reduction '{name}' with string dtype","messagePattern":"Cannot perform reduction '(.+?)' with string dtype","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/string_arrow.py","lineNumber":621,"sourceCode":"        nv.validate_minmax_axis(axis, self.ndim)\n        if self.dtype.na_value is np.nan and name in [\"any\", \"all\"]:\n            if not skipna:\n                nas = pc.is_null(self._pa_array)\n                arr = pc.or_kleene(nas, pc.not_equal(self._pa_array, \"\"))\n            else:\n                arr = pc.not_equal(self._pa_array, \"\")\n            result = ArrowExtensionArray(arr)._reduce(\n                name, skipna=skipna, keepdims=keepdims, **kwargs\n            )\n            if keepdims:\n                # ArrowExtensionArray will return a length-1 bool[pyarrow] array\n                return result.astype(np.bool_)\n            return result\n\n        if name in (\"count\", \"min\", \"max\", \"sum\", \"argmin\", \"argmax\"):\n            result = self._reduce_calc(name, skipna=skipna, keepdims=keepdims, **kwargs)\n        else:\n            raise TypeError(f\"Cannot perform reduction '{name}' with string dtype\")\n\n        if name in (\"argmin\", \"argmax\") and isinstance(result, pa.Array):\n            return self._convert_int_result(result)\n        elif isinstance(result, pa.Array):\n            return type(self)(result, dtype=self.dtype)\n        else:\n            return result\n\n    def value_counts(self, dropna: bool = True) -> Series:\n        result = super().value_counts(dropna=dropna)\n        if self.dtype.na_value is np.nan:\n            res_values = result._values.to_numpy()\n            return result._constructor(\n                res_values, index=result.index, name=result.name, copy=False\n            )\n        return result\n\n    def _cmp_method(self, other, op):","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/string_arrow.py#L603-L639","documentation":"Raised by ArrowStringArray._reduce() when the reduction name is not one of the supported set ('count','min','max','sum','argmin','argmax') nor the any/all fast path. String-typed reductions like 'mean','median','prod','std','var','sem' are mathematically undefined for text, so pandas rejects them with a TypeError naming the offending reduction.","triggerScenarios":"Calling `s.mean()`, `s.median()`, `s.std()`, `s.prod()`, `s.cumprod()` (via reduce), or `df.agg('mean')` on a column with dtype 'string[pyarrow]'. The else-branch at string_arrow.py:621 fires for any unsupported name.","commonSituations":"Running generic numeric aggregation pipelines (df.describe() numeric cols, .agg with a mean func) over a DataFrame without first selecting numeric columns; schema drift where a column that was numeric becomes string-typed.","solutions":["Select only numeric columns before aggregating: `df.select_dtypes('number').mean()`.","Cast the column to a numeric dtype if the data is actually numeric: `s.astype('float64').mean()`.","Use a supported string reduction: s.count(), s.min(), s.max(), or s.str.len().mean() for length-based stats.","Guard the agg call with a dtype check so string columns skip numeric funcs."],"exampleFix":"# before\ns = pd.Series(['1','2','3'], dtype='string[pyarrow]')\ns.mean()  # TypeError\n# after\ns.astype('int64').mean()\n# or: s.str.len().mean()","handlingStrategy":"validation","validationCode":"SUPPORTED = {'count','min','max','sum','argmin','argmax','any','all'}\n\ndef safe_reduce(s, name, **kw):\n    if name not in SUPPORTED:\n        if s.dtype.kind == 'f' or pd.api.types.is_integer_dtype(s):\n            return getattr(s.astype('float64'), name)(**kw)\n        raise TypeError(f'Unsupported reduction {name} for string dtype')\n    return getattr(s, name)(**kw)","typeGuard":"import pandas as pd\ndef is_numeric_series(s) -> bool:\n    return pd.api.types.is_numeric_dtype(s)","tryCatchPattern":"try:\n    return s.mean()\nexcept TypeError as e:\n    if 'Cannot perform reduction' in str(e):\n        return s.astype('float64').mean()\n    raise","preventionTips":["Filter DataFrames to numeric dtypes before numeric aggregations.","Maintain a schema registry so you know which columns are text.","Write agg specs per column kind rather than globally."],"tags":["string-arrow","reduction","aggregation","typeerror"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}