pandas-dev/pandas · error · TypeError

Cannot perform reduction '{name}' with string dtype

Error message

Cannot perform reduction '{name}' with string dtype

What it means

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.

Source

Thrown at pandas/core/arrays/string_arrow.py:621

        nv.validate_minmax_axis(axis, self.ndim)
        if self.dtype.na_value is np.nan and name in ["any", "all"]:
            if not skipna:
                nas = pc.is_null(self._pa_array)
                arr = pc.or_kleene(nas, pc.not_equal(self._pa_array, ""))
            else:
                arr = pc.not_equal(self._pa_array, "")
            result = ArrowExtensionArray(arr)._reduce(
                name, skipna=skipna, keepdims=keepdims, **kwargs
            )
            if keepdims:
                # ArrowExtensionArray will return a length-1 bool[pyarrow] array
                return result.astype(np.bool_)
            return result

        if name in ("count", "min", "max", "sum", "argmin", "argmax"):
            result = self._reduce_calc(name, skipna=skipna, keepdims=keepdims, **kwargs)
        else:
            raise TypeError(f"Cannot perform reduction '{name}' with string dtype")

        if name in ("argmin", "argmax") and isinstance(result, pa.Array):
            return self._convert_int_result(result)
        elif isinstance(result, pa.Array):
            return type(self)(result, dtype=self.dtype)
        else:
            return result

    def value_counts(self, dropna: bool = True) -> Series:
        result = super().value_counts(dropna=dropna)
        if self.dtype.na_value is np.nan:
            res_values = result._values.to_numpy()
            return result._constructor(
                res_values, index=result.index, name=result.name, copy=False
            )
        return result

    def _cmp_method(self, other, op):

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Select only numeric columns before aggregating: `df.select_dtypes('number').mean()`.
  2. Cast the column to a numeric dtype if the data is actually numeric: `s.astype('float64').mean()`.
  3. Use a supported string reduction: s.count(), s.min(), s.max(), or s.str.len().mean() for length-based stats.
  4. Guard the agg call with a dtype check so string columns skip numeric funcs.

Example fix

# before
s = pd.Series(['1','2','3'], dtype='string[pyarrow]')
s.mean()  # TypeError
# after
s.astype('int64').mean()
# or: s.str.len().mean()
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {'count','min','max','sum','argmin','argmax','any','all'}

def safe_reduce(s, name, **kw):
    if name not in SUPPORTED:
        if s.dtype.kind == 'f' or pd.api.types.is_integer_dtype(s):
            return getattr(s.astype('float64'), name)(**kw)
        raise TypeError(f'Unsupported reduction {name} for string dtype')
    return getattr(s, name)(**kw)

Type guard

import pandas as pd
def is_numeric_series(s) -> bool:
    return pd.api.types.is_numeric_dtype(s)

Try / catch

try:
    return s.mean()
except TypeError as e:
    if 'Cannot perform reduction' in str(e):
        return s.astype('float64').mean()
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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