{"record":{"id":"2ea9c9403da13758","repo":"pandas-dev/pandas","slug":"object-with-dtype-self-dtype-cannot-perform-the","errorCode":null,"errorMessage":"Object with dtype {self.dtype} cannot perform the numpy op {ufunc.__name__}","messagePattern":"Object with dtype (.+?) cannot perform the numpy op (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/categorical.py","lineNumber":1822,"sourceCode":"            return result\n\n        if \"out\" in kwargs:\n            # e.g. test_numpy_ufuncs_out\n            return arraylike.dispatch_ufunc_with_out(\n                self, ufunc, method, *inputs, **kwargs\n            )\n\n        if method == \"reduce\":\n            # e.g. TestCategoricalAnalytics::test_min_max_ordered\n            result = arraylike.dispatch_reduction_ufunc(\n                self, ufunc, method, *inputs, **kwargs\n            )\n            if result is not NotImplemented:\n                return result\n\n        # for all other cases, raise for now (similarly as what happens in\n        # Series.__array_prepare__)\n        raise TypeError(\n            f\"Object with dtype {self.dtype} cannot perform \"\n            f\"the numpy op {ufunc.__name__}\"\n        )\n\n    def __setstate__(self, state) -> None:\n        \"\"\"Necessary for making this object picklable\"\"\"\n        if not isinstance(state, dict):\n            return super().__setstate__(state)\n\n        if \"_dtype\" not in state:\n            state[\"_dtype\"] = CategoricalDtype(state[\"_categories\"], state[\"_ordered\"])\n\n        if \"_codes\" in state and \"_ndarray\" not in state:\n            # backward compat, changed what is property vs attribute\n            state[\"_ndarray\"] = state.pop(\"_codes\")\n\n        super().__setstate__(state)\n","sourceCodeStart":1804,"sourceCodeEnd":1840,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/categorical.py#L1804-L1840","documentation":"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.","triggerScenarios":"`np.sin(cat)`, `np.add(cat, 1)`, `cat + 1`, or any non-reduction numpy ufunc applied directly to a Categorical.","commonSituations":"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.","solutions":["Convert to the underlying values first: `np.sin(np.asarray(cat))`.","Use `cat.astype(<numeric dtype>)` if the categories are genuinely numeric and you want arithmetic.","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.","Operate on `cat.codes` only if positional integer math is genuinely intended."],"exampleFix":"# before\nimport numpy as np\nimport pandas as pd\ncat = pd.Categorical([1.0, 2.0, 3.0])\nout = np.sin(cat)  # TypeError\n\n# after\nout = np.sin(np.asarray(cat))\n# or, if numeric semantics are intended\ncat.astype('float64') + 1","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef apply_ufunc_to_cat(ufunc, cat, *args, **kwargs):\n    return ufunc(np.asarray(cat), *args, **kwargs)","typeGuard":"def ufunc_is_supported_on_cat(ufunc, cat) -> bool:\n    name = getattr(ufunc, '__name__', '')\n    if name in {'minimum', 'maximum', 'amin', 'amax'}:\n        return cat.ordered\n    return False","tryCatchPattern":"import numpy as np\ntry:\n    out = np.sin(cat)\nexcept TypeError as e:\n    if 'cannot perform the numpy op' in str(e):\n        out = np.sin(np.asarray(cat))\n    else:\n        raise","preventionTips":["Materialize via `np.asarray(cat)` before applying numeric ufuncs.","For reductions like min/max on ordered categoricals, use the supported `cat.min()`/`cat.max()` methods.","If you need arithmetic, cast the Categorical to a numeric dtype first."],"tags":["categorical","ufunc","numpy","typeerror"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}