{"record":{"id":"85c5c446cd3e1073","repo":"pola-rs/polars","slug":"could-not-find-apply-ufunc-numpy-char-code-to-dt","errorCode":null,"errorMessage":"could not find `apply_ufunc_{numpy_char_code_to_dtype(dtype_char)}`","messagePattern":"could not find `apply_ufunc_(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/series.py","lineNumber":1706,"sourceCode":"                ufunc_input, ufunc_output = ufunc.signature.split(\"->\")\n                if ufunc_output == \"()\":\n                    # If the result a scalar, just let the function do its\n                    # thing, no need for any song and dance involving\n                    # allocation:\n                    return ufunc(*args, dtype=dtype_char, **kwargs)\n                else:\n                    allocate_output = ufunc_input == ufunc_output\n            else:\n                allocate_output = True\n\n            f = get_ffi_func(\"apply_ufunc_<>\", numpy_char_code_to_dtype(dtype_char), s)\n\n            if f is None:\n                msg = (\n                    \"could not find \"\n                    f\"`apply_ufunc_{numpy_char_code_to_dtype(dtype_char)}`\"\n                )\n                raise NotImplementedError(msg)\n\n            series = f(\n                lambda out: ufunc(*args, out=out, dtype=dtype_char, **kwargs),\n                allocate_output,\n            )\n\n            result = self._from_pyseries(series)\n            if is_generalized_ufunc:\n                # In this case we've disallowed passing in missing data, so no\n                # further processing is needed.\n                return result\n\n            # We're using a regular ufunc, that operates value by value. That\n            # means we allowed missing data in the input, so filter it out:\n            validity_mask = self.is_not_null() if self.has_nulls() else F.lit(True)\n            for arg in inputs:\n                if isinstance(arg, Series) and arg.has_nulls():\n                    validity_mask &= arg.is_not_null()","sourceCodeStart":1688,"sourceCodeEnd":1724,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/series/series.py#L1688-L1724","documentation":"Raised in Series.__array_ufunc__ after dtype negotiation: the resolved numpy dtype character code (from the 'dtype' kwarg or np.result_type of the args) has no matching Rust `apply_ufunc_*` FFI kernel. Polars only ships kernels for its native numeric dtypes; complex ('D'/'F'), datetime64 ('M'), timedelta64 ('m'), and similar codes have no implementation, hence NotImplementedError naming the exact missing function.","triggerScenarios":"`np.multiply(s, np.array([1.5 + 2j]))` (result_type resolves 'D' -> apply_ufunc_Complex128 missing), `np.add(s, np.array(['2024-01-01'], 'datetime64[D]'))`, passing dtype='complex128' via kwargs, or a ufunc whose only output types are unsupported codes (filtered dtypes_ufunc list ends up empty).","commonSituations":"DSP/signal code introducing complex ndarrays alongside a Series; feeding np.datetime64 arrays from external data into ufunc calls; rare int codes on platforms where the Rust side lacks a kernel.","solutions":["Detach to numpy for exotic dtypes and wrap the result back: `pl.Series(np.multiply(s.to_numpy(), np.array([1 + 2j])))`.","Cast the offending operand to float64 before the call: `np.multiply(s, complex_arr.astype(np.float64))` when imaginary parts are known-zero.","Remove explicit dtype= kwargs that force an unsupported dtype.","Upgrade Polars - the set of apply_ufunc kernels grows across releases; the error names the exact kernel it wanted."],"exampleFix":"// before\nnp.multiply(s, np.array([1.5 + 2j]))  # NotImplementedError: apply_ufunc_...\n\n// after\npl.Series(np.multiply(s.to_numpy(), np.array([1.5 + 2j])))","handlingStrategy":"validation","validationCode":"SUPPORTED = set('bhilqefdg?')  # codes with apply_ufunc_ kernels\nif np.result_type(*args).char not in SUPPORTED:\n    out = pl.Series(ufunc(*[a.to_numpy() if isinstance(a, pl.Series) else a for a in args]))\nelse:\n    out = ufunc(*args)","typeGuard":"def is_supported_ufunc_dtype(args) -> bool:\n    import numpy as np\n    return np.result_type(*args).char in set('bhilqefdg')","tryCatchPattern":"try:\n    out = np.multiply(s, arr)\nexcept NotImplementedError as e:\n    if 'apply_ufunc_' not in str(e):\n        raise\n    out = pl.Series(np.multiply(s.to_numpy(), arr))","preventionTips":["Keep complex ('D'/'F'), datetime64 ('M'), timedelta64 ('m') operands out of Series ufunc calls.","Detach to numpy for exotic dtypes and rewrap with pl.Series afterwards.","The error text names the missing kernel - read it to identify the offending dtype."],"tags":["polars","series","numpy","ufunc","ffi","complex-numbers","dtype"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}