{"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/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/categorical.py#L1804-L1840","documentation":"Raised by Categorical.__array_ufunc__ when a numpy ufunc cannot be dispatched to a dunder operation, an out= reduction, or a reduce. Categorical is a categorical-codes array, so most numpy elementwise ufuncs (e.g. np.add, np.multiply on the category values) have no meaningful definition and pandas refuses to silently broadcast over codes. This is the final fallback after every dispatch attempt returns NotImplemented. It exists to prevent silent, semantically wrong results from treating integer codes as data.","triggerScenarios":"Calling a numpy ufunc directly on a Categorical or a Series/Index backed by one where no dunder-op dispatch exists: np.add(cat, 1), np.sin(cat), np.logical_and(cat, cat), or np.ufunc.reduce variants that are not min/max/sum-style reductions pandas knows how to handle. Also triggered via np.array(...) coercion paths that route through __array_ufunc__.","commonSituations":"Passing a categorical Series into a numeric numpy routine during feature engineering, calling np.where on a categorical mask, applying sklearn/numpy pipelines that assume numeric arrays, or upgrading numpy versions where new ufunc dispatch paths surface this guard.","solutions":["Convert the categorical to its underlying values with .astype(categories.dtype) or cat.to_numpy() before applying the numpy ufunc.","Use the .cat.codes accessor if you genuinely want integer-code semantics.","Replace the numpy ufunc with the equivalent pandas/Series method (e.g. Series.add, Series.eq) which dispatches correctly."],"exampleFix":"// before\nimport numpy as np\ncat = pd.Categorical([\"a\",\"b\",\"c\"])\nnp.add(cat, 1)  # TypeError\n\n// after\ncat.to_numpy()  # array(['a','b','c'], dtype=object)","handlingStrategy":"type-guard","validationCode":"def safe_ufunc(cat, ufunc, *args, **kwargs):\n    import pandas as pd\n    if isinstance(cat.dtype, pd.CategoricalDtype):\n        raise TypeError(f\"ufunc {ufunc.__name__} not defined on Categorical; convert first\")\n    return ufunc(cat, *args, **kwargs)","typeGuard":"import pandas as pd\nfrom typing import Any\n\ndef is_categorical(obj: Any) -> bool:\n    return isinstance(getattr(obj, 'dtype', None), pd.CategoricalDtype)","tryCatchPattern":"try:\n    np.add(cat, 1)\nexcept TypeError as e:\n    if 'cannot perform the numpy op' in str(e):\n        result = np.add(cat.to_numpy(), 1)\n    else:\n        raise","preventionTips":["Never pass a Categorical directly to a numpy ufunc; call .to_numpy() first.","Prefer pandas Series methods over numpy ufuncs for category-backed Series."],"tags":["categorical","numpy-ufunc","dtype"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}