pandas-dev/pandas · error · TypeError

Object with dtype cannot perform the numpy op

Error message

Object with dtype {self.dtype} cannot perform the numpy op {ufunc.__name__}

What it means

Raised by `Categorical.__array_ufunc__` for numpy ufuncs that are neither equality-like nor handled by `dispatch_reduction_ufunc` (e.g. `reduce` method of `np.min`/`np.max`). Categoricals do not support arbitrary numerical ufuncs because their codes are positional, not numeric — applying e.g. `np.sin` to codes would be meaningless.

Solutions

  1. Convert to the underlying values first: `np.sin(np.asarray(cat))`.
  2. Use `cat.astype(<numeric dtype>)` if the categories are genuinely numeric and you want arithmetic.
  3. For reductions like min/max on ordered categoricals, use `cat.min()`/`cat.max()` or `np.min(cat)`/`np.max(cat)` which dispatch through the supported reduce path.
  4. Operate on `cat.codes` only if positional integer math is genuinely intended.

Example fix

# before
import numpy as np
import pandas as pd
cat = pd.Categorical([1.0, 2.0, 3.0])
out = np.sin(cat)  # TypeError

# after
out = np.sin(np.asarray(cat))
# or, if numeric semantics are intended
cat.astype('float64') + 1
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def apply_ufunc_to_cat(ufunc, cat, *args, **kwargs):
    return ufunc(np.asarray(cat), *args, **kwargs)

Type guard

def ufunc_is_supported_on_cat(ufunc, cat) -> bool:
    name = getattr(ufunc, '__name__', '')
    if name in {'minimum', 'maximum', 'amin', 'amax'}:
        return cat.ordered
    return False

Try / catch

import numpy as np
try:
    out = np.sin(cat)
except TypeError as e:
    if 'cannot perform the numpy op' in str(e):
        out = np.sin(np.asarray(cat))
    else:
        raise

Prevention

When it happens

Trigger: `np.sin(cat)`, `np.add(cat, 1)`, `cat + 1`, or any non-reduction numpy ufunc applied directly to a Categorical.

Common situations: Treating a numeric-valued categorical as if it were a plain numeric array; vectorized math over a column that was cast to category for storage efficiency; library code that calls ufuncs generically on object dtype.

Related errors


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

Appendix: source

Thrown at pandas/core/arrays/categorical.py:1822

            return result

        if "out" in kwargs:
            # e.g. test_numpy_ufuncs_out
            return arraylike.dispatch_ufunc_with_out(
                self, ufunc, method, *inputs, **kwargs
            )

        if method == "reduce":
            # e.g. TestCategoricalAnalytics::test_min_max_ordered
            result = arraylike.dispatch_reduction_ufunc(
                self, ufunc, method, *inputs, **kwargs
            )
            if result is not NotImplemented:
                return result

        # for all other cases, raise for now (similarly as what happens in
        # Series.__array_prepare__)
        raise TypeError(
            f"Object with dtype {self.dtype} cannot perform "
            f"the numpy op {ufunc.__name__}"
        )

    def __setstate__(self, state) -> None:
        """Necessary for making this object picklable"""
        if not isinstance(state, dict):
            return super().__setstate__(state)

        if "_dtype" not in state:
            state["_dtype"] = CategoricalDtype(state["_categories"], state["_ordered"])

        if "_codes" in state and "_ndarray" not in state:
            # backward compat, changed what is property vs attribute
            state["_ndarray"] = state.pop("_codes")

        super().__setstate__(state)

View on GitHub (pinned to 3b7651241d)