pola-rs/polars · error

could not find `apply_ufunc_{numpy_char_code_to_dtype(dtype_

Error message

could not find `apply_ufunc_{numpy_char_code_to_dtype(dtype_char)}`

What it means

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.

Source

Thrown at py-polars/src/polars/series/series.py:1706

                ufunc_input, ufunc_output = ufunc.signature.split("->")
                if ufunc_output == "()":
                    # If the result a scalar, just let the function do its
                    # thing, no need for any song and dance involving
                    # allocation:
                    return ufunc(*args, dtype=dtype_char, **kwargs)
                else:
                    allocate_output = ufunc_input == ufunc_output
            else:
                allocate_output = True

            f = get_ffi_func("apply_ufunc_<>", numpy_char_code_to_dtype(dtype_char), s)

            if f is None:
                msg = (
                    "could not find "
                    f"`apply_ufunc_{numpy_char_code_to_dtype(dtype_char)}`"
                )
                raise NotImplementedError(msg)

            series = f(
                lambda out: ufunc(*args, out=out, dtype=dtype_char, **kwargs),
                allocate_output,
            )

            result = self._from_pyseries(series)
            if is_generalized_ufunc:
                # In this case we've disallowed passing in missing data, so no
                # further processing is needed.
                return result

            # We're using a regular ufunc, that operates value by value. That
            # means we allowed missing data in the input, so filter it out:
            validity_mask = self.is_not_null() if self.has_nulls() else F.lit(True)
            for arg in inputs:
                if isinstance(arg, Series) and arg.has_nulls():
                    validity_mask &= arg.is_not_null()

View on GitHub (pinned to df599052da)

Solutions

  1. Detach to numpy for exotic dtypes and wrap the result back: `pl.Series(np.multiply(s.to_numpy(), np.array([1 + 2j])))`.
  2. Cast the offending operand to float64 before the call: `np.multiply(s, complex_arr.astype(np.float64))` when imaginary parts are known-zero.
  3. Remove explicit dtype= kwargs that force an unsupported dtype.
  4. Upgrade Polars - the set of apply_ufunc kernels grows across releases; the error names the exact kernel it wanted.

Example fix

// before
np.multiply(s, np.array([1.5 + 2j]))  # NotImplementedError: apply_ufunc_...

// after
pl.Series(np.multiply(s.to_numpy(), np.array([1.5 + 2j])))
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = set('bhilqefdg?')  # codes with apply_ufunc_ kernels
if np.result_type(*args).char not in SUPPORTED:
    out = pl.Series(ufunc(*[a.to_numpy() if isinstance(a, pl.Series) else a for a in args]))
else:
    out = ufunc(*args)

Type guard

def is_supported_ufunc_dtype(args) -> bool:
    import numpy as np
    return np.result_type(*args).char in set('bhilqefdg')

Try / catch

try:
    out = np.multiply(s, arr)
except NotImplementedError as e:
    if 'apply_ufunc_' not in str(e):
        raise
    out = pl.Series(np.multiply(s.to_numpy(), arr))

Prevention

When it happens

Trigger: `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).

Common situations: 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.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/85c5c446cd3e1073. Report an issue: GitHub.