{"record":{"id":"2c0ac5dc71d6f0c1","repo":"pandas-dev/pandas","slug":"the-numba-engine-doesn-t-support-using-a-numpy-u","errorCode":null,"errorMessage":"the 'numba' engine doesn't support using a numpy ufunc as the callable function","messagePattern":"the 'numba' engine doesn't support using a numpy ufunc as the callable function","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":1036,"sourceCode":"            return self.apply_list_or_dict_like()\n\n        # all empty\n        if len(self.columns) == 0 and len(self.index) == 0:\n            return self.apply_empty_result()\n\n        # string dispatch\n        if isinstance(self.func, str):\n            if self.engine == \"numba\":\n                raise NotImplementedError(\n                    \"the 'numba' engine doesn't support using \"\n                    \"a string as the callable function\"\n                )\n            return self.apply_str()\n\n        # ufunc\n        elif isinstance(self.func, np.ufunc):\n            if self.engine == \"numba\":\n                raise NotImplementedError(\n                    \"the 'numba' engine doesn't support \"\n                    \"using a numpy ufunc as the callable function\"\n                )\n            with np.errstate(all=\"ignore\"):\n                results = self.obj._mgr.apply(\"apply\", func=self.func)\n            # _constructor will retain self.index and self.columns\n            return self.obj._constructor_from_mgr(results, axes=results.axes)\n\n        # broadcasting\n        if self.result_type == \"broadcast\":\n            if self.engine == \"numba\":\n                raise NotImplementedError(\n                    \"the 'numba' engine doesn't support result_type='broadcast'\"\n                )\n            return self.apply_broadcast(self.obj)\n\n        # one axis empty\n        elif not all(self.obj.shape):","sourceCodeStart":1018,"sourceCodeEnd":1054,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/apply.py#L1018-L1054","documentation":"Raised by DataFrame.apply / Series.apply when the user passes engine='numba' alongside a numpy ufunc (e.g. np.add, np.sqrt) as the func argument. The numba code path only JIT-compiles user-supplied Python callables; numpy ufuncs are C-level functions that numba cannot trace, so the combination is rejected up front in pandas/core/apply.py:1036. The error is a NotImplementedError, signaling that the feature is intentionally unsupported rather than buggy.","triggerScenarios":"Calling df.apply(np.negative, engine='numba'), df.apply(np.add, engine='numba'), or any df.apply(...)/s.apply(...) where func is an instance of np.ufunc and engine='numba' is also passed (with raw=False). Triggered in the NDFrame.apply path at apply.py:1034-1039.","commonSituations":"Developers migrating a hot loop to numba for speed and assuming any numpy function works; passing np.<something> as a shortcut instead of writing a @numba.njit-decorated function; copying examples from non-numba code into an engine='numba' call.","solutions":["Drop engine='numba' if you must use a numpy ufunc: df.apply(np.negative) (default 'python' engine handles ufuncs natively).","If you need numba speedups, write a @njit Python function and pass that as func instead of the numpy ufunc.","For elementwise ufunc math on a DataFrame, skip apply entirely and call the ufunc directly: np.negative(df) or df * -1, which dispatches via __array_ufunc__."],"exampleFix":"// before\ndf.apply(np.negative, engine='numba')\n// after\ndf.apply(np.negative)  # uses python engine, ufunc fast-path\n// or\nimport numba\n@numba.njit\ndef neg(x):\n    return -x\ndf.apply(neg, engine='numba', raw=True)","handlingStrategy":"validation","validationCode":"import numpy as np\nif engine == 'numba' and isinstance(func, np.ufunc):\n    raise ValueError('numpy ufuncs are unsupported with engine=numba; use a @njit function or drop engine=numba')","typeGuard":"def is_numba_safe_func(func, engine: str) -> bool:\n    import numpy as np\n    if engine != 'numba':\n        return True\n    return not isinstance(func, np.ufunc) and not isinstance(func, str)","tryCatchPattern":"try:\n    df.apply(func, engine=engine)\nexcept NotImplementedError as e:\n    if \"numba\" in str(e) and \"ufunc\" in str(e):\n        df.apply(func)  # fall back to python engine\n    else:\n        raise","preventionTips":["When opting into engine='numba', always pass a @numba.njit-decorated Python function, never np.<name>.","Gate engine selection on func type: use 'python' for ufuncs, 'numba' only for njit functions."],"tags":["pandas","numba","apply","ufunc","engine"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}