pandas-dev/pandas · error · NotImplementedError

function is not implemented for this dtype

Error message

function is not implemented for this dtype: {self.dtype}

What it means

_grouped_reduce only implements the cython groupby path for StringDtype (plus first/last handled earlier). For any other ExtensionArray dtype that reaches this branch, there is no cython implementation wired up, so it raises NotImplementedError naming the dtype. This indicates the custom EA has not integrated with pandas' groupby cython acceleration.

Solutions

  1. Cast the column to a backed numpy dtype before aggregating: df['col'] = df['col'].astype('float64') (accepting loss of NA semantics).
  2. Implement _grouped_reduce on the subclass to dispatch to a cython/numba routine for your dtype, mirroring the StringDtype branch.
  3. Aggregate only the supported columns and exclude the custom-EA column from the groupby reduction.

Example fix

// before
df.groupby('g').sum()  # NotImplementedError: function is not implemented for this dtype: MyDtype

// after
num_cols = df.select_dtypes(include='number').columns
df.groupby('g')[list(num_cols)].sum()
# or convert the custom column
out = df['custom'].astype('float64').groupby(df['g']).sum()
Defensive patterns

Strategy: fallback

Validate before calling

from pandas.core.arrays.string_ import StringDtype
if not isinstance(arr.dtype, StringDtype):
    # _grouped_reduce only handles StringDtype (and first/last); cast to numpy
    arr = arr.astype('float64')
_ = arr

Type guard

def supports_groupby_reduce(arr) -> bool:
    from pandas.core.arrays.string_ import StringDtype
    return isinstance(arr.dtype, StringDtype) or not isinstance(arr, __import__('pandas').api.extensions.ExtensionArray)

Try / catch

try:
    out = df.groupby('g').sum()
except NotImplementedError:
    num = df.select_dtypes(include='number').columns
    out = df.groupby('g')[list(num)].sum()

Prevention

When it happens

Trigger: Calling a groupby aggregation (sum, mean, min, max, etc. — but not first/last which are handled earlier) on a Series/DataFrame backed by a custom (non-StringDtype, non-numpy-backed) ExtensionArray. The aggregation routes to ExtensionArray._grouped_reduce, finds no matching dtype branch, and raises.

Common situations: A third-party extension dtype used as a groupby target without groupby-reduce support. A custom EA that supports scalar reductions but not the cython groupby path. Reaching this via df.groupby(...).agg(...) on a frame containing such a column.

Related errors


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

Appendix: source

Thrown at pandas/core/arrays/base.py:3093

            ]:
                raise TypeError(
                    f"dtype '{self.dtype}' does not support operation '{how}'"
                )
            if op.how not in ["any", "all"]:
                # Fail early to avoid conversion to object
                op._get_cython_function(op.kind, op.how, np.dtype(object), False)

            arr = self
            if op.how == "sum":
                initial = ""
                # https://github.com/pandas-dev/pandas/issues/60229
                # All NA should result in the empty string.
                assert "skipna" in kwargs
                if kwargs["skipna"] and min_count == 0:
                    arr = arr.fillna("")
            npvalues = arr.to_numpy(object, na_value=np.nan)
        else:
            raise NotImplementedError(
                f"function is not implemented for this dtype: {self.dtype}"
            )

        res_values = op._cython_op_ndim_compat(
            npvalues,
            min_count=min_count,
            ngroups=ngroups,
            comp_ids=ids,
            mask=None,
            initial=initial,
            **kwargs,
        )

        if op.how in op.cast_blocklist:
            # i.e. how in ["rank"], since other cast_blocklist methods don't go
            #  through cython_operation
            return res_values

View on GitHub (pinned to 3b7651241d)