pola-rs/polars · error · NotImplementedError
could not find `apply_ufunc_
Error message
could not find `apply_ufunc_{numpy_char_code_to_dtype(dtype_char)}` What it means
After determining the minimum numpy dtype char for a ufunc, polars looks up a compiled helper named apply_ufunc_<dtype> in its Rust core to run the ufunc with that dtype. If no such helper exists for the resolved dtype char, it raises NotImplementedError.
Solutions
- Cast inputs to a supported dtype first, e.g. srs.cast(pl.Float64)
- Avoid dtypes that promote to unsupported result types (use float64/int64/float32)
- Perform the ufunc in numpy and rebuild the Series from the result
Example fix
// before np.exp(srs.cast(pl.Float16)) // after np.exp(srs.cast(pl.Float64))
Defensive patterns
Strategy: type-guard
Validate before calling
assert srs.dtype in (pl.Int64, pl.Float64, pl.Float32, pl.Int32), f"unsupported ufunc dtype {srs.dtype}" Type guard
def ufunc_safe_dtype(dt: pl.DataType) -> bool:
return dt in (pl.Int8, pl.Int16, pl.Int32, pl.Int64, pl.UInt8, pl.UInt16, pl.UInt32, pl.UInt64, pl.Float32, pl.Float64) Try / catch
try:
out = np.exp(srs)
except NotImplementedError:
out = np.exp(srs.cast(pl.Float64)) Prevention
- Stick to common numeric dtypes (float64/int64) before ufuncs
- Avoid float16/complex promotions on Series
- Cast explicitly rather than relying on np.result_type promotion
When it happens
Trigger: Calling a numpy ufunc on a Series whose arguments resolve to a dtype char with no registered apply_ufunc_* helper (e.g. exotic result types from np.result_type such as complex/float16 in some builds, or object dtype).
Common situations: Using ufuncs that promote to an unusual dtype (e.g. np.float16 result, complex128) not covered by polars' ufunc dispatch table.
Related errors
- only `__call__` is implemented for numpy ufuncs on a…
- only ufuncs that return one 1D array are supported
- can't pass a Series with missing data to a generalized…
- cannot convert DataFrame to
- cannot convert List column
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/85c5c446cd3e1073.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/series/series.py:1592
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 fe841f959e)