pola-rs/polars · error

only `__call__` is implemented for numpy ufuncs on a Series,

Error message

only `__call__` is implemented for numpy ufuncs on a Series, got `{method!r}`

What it means

Raised in Series.__array_ufunc__ when numpy invokes a ufunc method other than plain '__call__' - e.g. 'reduce', 'outer', 'accumulate', 'at', or 'reduceat'. Polars only implements the elementwise call path through its Rust kernels; reductions and outer products have no Series-dispatch implementation.

Source

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

                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()
            return (
                result.to_frame()
                .select(F.when(validity_mask).then(F.col(self.name)))
                .to_series(0)
            )
        else:
            msg = (
                "only `__call__` is implemented for numpy ufuncs on a Series, got "
                f"`{method!r}`"
            )
            raise NotImplementedError(msg)

    def __arrow_c_stream__(self, requested_schema: object | None = None) -> object:
        """
        Export a Series via the Arrow PyCapsule Interface.

        https://arrow.apache.org/docs/dev/format/CDataInterface/PyCapsuleInterface.html
        """
        return self._s.__arrow_c_stream__(requested_schema)

    def _repr_html_(self) -> str_:
        """Format output data in HTML for display in Jupyter Notebooks."""
        return self.to_frame()._repr_html_(_from_series=True)

    def item(self, index: int | None = None) -> Any:
        """
        Return the Series as a scalar, or return the element at the given index.

        If no index is provided, this is equivalent to `s[0]`, with a check

View on GitHub (pinned to df599052da)

Solutions

  1. Use Polars' native equivalents: `s.sum()`, `s.min()`, `s.max()`, `s.cum_sum()`, `s.cum_max()`.
  2. For reduce over axes on 2D data, convert first: `np.add.reduce(s.to_numpy())`.
  3. For outer products: `np.add.outer(s.to_numpy(), s.to_numpy())` and rewrap with pl.Series if needed.
  4. In generic code, route on method: only pass '__call__' through the Series protocol; send other methods to the numpy array path.

Example fix

// before
np.add.reduce(s)  # NotImplementedError

// after
s.sum()
# or
np.add.reduce(s.to_numpy())
Defensive patterns

Strategy: fallback

Validate before calling

if method != '__call__':
    result = getattr(ufunc, method)(s.to_numpy(), **kwargs)
else:
    result = ufunc(s, **kwargs)

Type guard

def is_call_method(method: str) -> bool:
    return method == '__call__'

Try / catch

try:
    out = np.add.reduce(s)
except NotImplementedError:
    out = s.sum()  # or np.add.reduce(s.to_numpy())

Prevention

When it happens

Trigger: `np.add.reduce(s)` (sum), `np.maximum.reduce(s)` (max), `np.add.accumulate(s)` (cumsum), `np.add.outer(s, s)`, `np.subtract.at(...)`. The else-branch of `if method == '__call__'` catches all of these.

Common situations: Aggregation code using np.<ufunc>.reduce instead of native sums; cumsum via np.add.accumulate ported from numpy pipelines; outer-product construction for pairwise features.

Related errors


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