{"record":{"id":"43897734f5ef944c","repo":"pandas-dev/pandas","slug":"cannot-perform-name-with-type-self-dtype-438977","errorCode":null,"errorMessage":"cannot perform {name} with type {self.dtype}","messagePattern":"cannot perform (.+?) with type (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/array.py","lineNumber":1571,"sourceCode":"            self.__dict__.update(state)\n\n    def nonzero(self) -> tuple[npt.NDArray[np.int32]]:\n        if self.fill_value == 0:\n            return (self.sp_index.indices,)\n        else:\n            return (self.sp_index.indices[self.sp_values != 0],)\n\n    # ------------------------------------------------------------------------\n    # Reductions\n    # ------------------------------------------------------------------------\n\n    def _reduce(\n        self, name: str, *, skipna: bool = True, keepdims: bool = False, **kwargs\n    ):\n        method = getattr(self, name, None)\n\n        if method is None:\n            raise TypeError(f\"cannot perform {name} with type {self.dtype}\")\n\n        if name in (\"mean\", \"sum\", \"min\", \"max\"):\n            # these methods handle skipna themselves; dropping NAs beforehand\n            # would hide the NA from their skipna=False short-circuit\n            result = method(skipna=skipna, **kwargs)\n        else:\n            if skipna:\n                arr = self\n            else:\n                arr = self.dropna()\n            result = getattr(arr, name)(**kwargs)\n\n        if keepdims:\n            return type(self)([result], dtype=self.dtype)\n        else:\n            return result\n\n    def all(self, axis=None, *args, **kwargs):","sourceCodeStart":1553,"sourceCodeEnd":1589,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/sparse/array.py#L1553-L1589","documentation":"Raised by SparseArray._reduce when the reduction name (e.g. 'median', 'prod', 'sem') has no corresponding method on the SparseArray class. The dispatcher looks up getattr(self, name) and, if missing, refuses with the dtype in the message so the caller knows which operation is unsupported for this ExtensionArray type.","triggerScenarios":"Series(sparse).median(), df.agg('sem') on a sparse column, np.nanmedian(sparse_series), or df.prod() on a Sparse[int64] column where the op is not implemented.","commonSituations":"Calling a reduction that pandas implements densely but not for sparse arrays, or applying a generic .agg([...]) list that includes unsupported names across heterogeneous columns.","solutions":["Reduce the dense version: float(sparse_arr.to_dense().median()).","Drop unsupported reduction names from the .agg list, or guard per-column by dtype.","Implement a custom reducer and call it explicitly rather than via the generic _reduce dispatcher."],"exampleFix":"// before\nm = sparse_series.median()  # raises 'cannot perform median ...'\n\n// after\nm = sparse_series.to_dense().median()","handlingStrategy":"fallback","validationCode":"SUPPORTED_SPARSE_REDUCTIONS = {'sum', 'mean', 'min', 'max', 'all', 'any', 'prod'}\n\ndef reduce_sparse_safe(arr, name, **kw):\n    if name in SUPPORTED_SPARSE_REDUCTIONS and hasattr(arr, name):\n        return getattr(arr, name)(**kw)\n    return getattr(arr.to_dense(), name)(**kw)","typeGuard":"def sparse_supports_reduction(arr, name) -> bool:\n    return hasattr(arr, name)","tryCatchPattern":"try:\n    res = sparse_series.agg(name)\nexcept TypeError as e:\n    if 'cannot perform' in str(e):\n        res = sparse_series.to_dense().agg(name)\n    else:\n        raise","preventionTips":["Filter .agg([...]) lists to reductions supported per dtype","Fall back to .to_dense() for unsupported reductions like median/sem","Guard generic reduction dispatchers with hasattr checks"],"tags":["sparse","reductions","dtype","unsupported"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}