{"record":{"id":"fdd768c5c103304c","repo":"pandas-dev/pandas","slug":"dtype-self-dtype-does-not-support-operation","errorCode":null,"errorMessage":"dtype '{self.dtype}' does not support operation '{how}'","messagePattern":"dtype '(.+?)' does not support operation '(.+?)'","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/array.py","lineNumber":3539,"sourceCode":"        has_dropped_na: bool,\n        min_count: int,\n        ngroups: int,\n        ids: npt.NDArray[np.intp],\n        **kwargs,\n    ):\n        if isinstance(self.dtype, StringDtype):\n            if how in [\n                \"prod\",\n                \"mean\",\n                \"median\",\n                \"cumsum\",\n                \"cumprod\",\n                \"std\",\n                \"sem\",\n                \"var\",\n                \"skew\",\n            ]:\n                raise TypeError(\n                    f\"dtype '{self.dtype}' does not support operation '{how}'\"\n                )\n            # Fall through to Arrow-native path below\n\n        pa_type = self._pa_array.type\n\n        # Try PyArrow-native path for decimal and string types where it's faster.\n        # For integer/float/boolean, the fallback path via _to_masked() is faster.\n        if (\n            pa.types.is_decimal(pa_type)\n            or pa.types.is_string(pa_type)\n            or pa.types.is_large_string(pa_type)\n        ):\n            native_result = self._groupby_op_pyarrow(\n                how=how,\n                min_count=min_count,\n                ngroups=ngroups,\n                ids=ids,","sourceCodeStart":3521,"sourceCodeEnd":3557,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/arrow/array.py#L3521-L3557","documentation":"_groupby_op explicitly rejects a list of mathematically-undefined reductions (prod, mean, median, cumsum, cumprod, std, sem, var, skew) for StringDtype-backed-by-arrow arrays, raising TypeError. Even though pyarrow has some kernels, these operations are semantically meaningless on strings, so pandas short-circuits before dispatch.","triggerScenarios":"Grouping a string[pyarrow] column and calling .prod()/.mean()/.median()/.cumsum()/.cumprod()/.std()/.sem()/.var()/.skew() on the groupby result.","commonSituations":"df.groupby('key').agg(['mean','std']) on a frame with string columns; applying numeric aggregations to every column without dtype filtering.","solutions":["Filter columns by numeric dtype before grouping: df.select_dtypes('number').groupby(key).mean().","Use a string-appropriate aggregation: .count, .first, .last, .sum (concatenation is allowed), .size.","Build a per-column aggregation dictionary excluding string columns."],"exampleFix":"// before\ndf = pd.DataFrame({\"k\": [\"a\", \"a\"], \"v\": [\"x\", \"y\"]}, dtype={\"v\": \"string[pyarrow]\"})\ndf.groupby(\"k\")[\"v\"].mean()\n// after\ndf = pd.DataFrame({\"k\": [\"a\", \"a\"], \"v\": [1, 2]}, dtype={\"v\": \"int64[pyarrow]\"})\ndf.groupby(\"k\")[\"v\"].mean()","handlingStrategy":"validation","validationCode":"STRING_UNSUPPORTED = {\"prod\",\"mean\",\"median\",\"cumsum\",\"cumprod\",\"std\",\"sem\",\"var\",\"skew\"}\n\ndef groupby_op_supported(dtype, how) -> bool:\n    from pandas.core.arrays.string_ import StringDtype\n    if isinstance(dtype, StringDtype) and how in STRING_UNSUPPORTED:\n        return False\n    return True","typeGuard":"def is_string_arrow_dtype(dtype) -> bool:\n    from pandas.core.arrays.string_ import StringDtype\n    return isinstance(dtype, StringDtype)","tryCatchPattern":"try:\n    df.groupby(\"k\")[col].mean()\nexcept TypeError:\n    # skip non-numeric columns\n    df.select_dtypes(\"number\").groupby(\"k\").mean()","preventionTips":["Filter numeric columns before applying numeric groupby reductions.","Build explicit agg dicts per column dtype."],"tags":["pyarrow","groupby","string-dtype","typeerror"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}