There is currently no rolling_product
in Polars. You can construct yourself using rolling_apply
as you say, but this is not the most efficient as it recomputes the product over each window every time as you have found out.
I can think of two possible solutions that may be faster by avoiding complete recomputation and can readily be implemented using existing methods. Note, haven't benchmarked either of these, and for sure a specialized implementation will beat these approaches.
- use cumprod to generate the cumulative product, and then shift
this X periods, where X is your window for the rolling product, to generate the lagged version. Take the ratio of the unlagged and the lagged version.
- use that
a * b
can be written as exp(log(a) + log(b))
. So you could do something like
pl.col("a").log().rolling_sum(...).exp()
This may introduce numeric instabilities though, and wont work with non-positive numbers.