pandas-dev/pandas · error · TypeError

cannot perform with type

Error message

cannot perform {name} with type {self.dtype}

What it means

TypeError from SparseArray._reduce when no method matching the reduction name exists on the SparseArray (e.g. 'median', 'prod' not implemented). The reduction dispatcher (used by Series.describe/agg/reduce) only forwards names that the ExtensionArray exposes.

Solutions

  1. Reduce on the dense equivalent: getattr(np.asarray(arr), name)() or pd.Series(np.asarray(arr)).agg(name).
  2. Filter the reduction list to those SparseArray supports (sum, min, max, mean, etc.).
  3. Register a custom reduction via ExtensionArray if you need sparse-aware behavior.

Example fix

// before
pd.Series(arr).agg('median')  # raises for unsupported name
// after
pd.Series(np.asarray(arr)).agg('median')
Defensive patterns

Strategy: validation

Validate before calling

SPARSE_REDUCTIONS = {'sum', 'min', 'max', 'mean', 'prod'}
def safe_reduce(arr, name, **kw):
    if hasattr(arr, name):
        return getattr(arr, name)(**kw)
    import numpy as np
    return getattr(np.asarray(arr), name)(**kw)

Type guard

def sparse_supports_reduction(arr, name) -> bool:
    return hasattr(arr, name)

Try / catch

try:
    pd.Series(arr).agg(name)
except TypeError as e:
    if 'cannot perform' in str(e):
        import numpy as np
        out = getattr(np.asarray(arr), name)()
    else:
        raise

Prevention

When it happens

Trigger: pd.Series(sparse_arr).agg('median'); df.sparse_col.mean() works but df.sparse_col.prod() may not; calling arr._reduce('skew').

Common situations: Aggregating sparse columns with reduction names pandas does not implement for SparseArray; generic agg over a list of reductions where some are unsupported.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/43897734f5ef944c. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/sparse/array.py:1605

            self.__dict__.update(state)

    def nonzero(self) -> tuple[npt.NDArray[np.int32]]:
        if self.fill_value == 0:
            return (self.sp_index.indices,)
        else:
            return (self.sp_index.indices[self.sp_values != 0],)

    # ------------------------------------------------------------------------
    # Reductions
    # ------------------------------------------------------------------------

    def _reduce(
        self, name: str, *, skipna: bool = True, keepdims: bool = False, **kwargs
    ):
        method = getattr(self, name, None)

        if method is None:
            raise TypeError(f"cannot perform {name} with type {self.dtype}")

        if name in ("mean", "sum", "min", "max"):
            # these methods handle skipna themselves; dropping NAs beforehand
            # would hide the NA from their skipna=False short-circuit
            result = method(skipna=skipna, **kwargs)
        else:
            if skipna:
                arr = self
            else:
                arr = self.dropna()
            result = getattr(arr, name)(**kwargs)

        if keepdims:
            return type(self)([result], dtype=self.dtype)
        else:
            return result

    def all(self, axis=None, *args, **kwargs):

View on GitHub (pinned to 3b7651241d)