I have a frequently occurring problem where I have two arrays of the same length: one with values and one with dynamic decay factors; and wish to calculate a vector of the decayed cumulative sum at each position. Using a Python loop to express the desired recurrence we have the following:
c = np.empty_like(x)
c[0] = x[0]
for i in range(1, len(x)):
c[i] = c[i-1] * d[i] + x[i]
The Python code is very clear and readable, but slows things down significantly. I can get around this by using Numba to JIT-compile it, or Cython to precompile it. If the discount factors were a fixed number (which is not the case), I could have used SciPy's signals library and do an lfilter (see https://stackoverflow.com/a/47971187/1017986).
Is there a more "Numpythonic" way to express this without sacrificing clarity or efficiency?
x[i]elements from the loop and add the whole array later withc[1:] += x[1:]. It's only part of the problem though.ufunchave anaccumulatemethod, which is used in functions likecumsum. But it's hard generalize this, or use the usual parallel oriented numpy building blocks. So numba/cython is the best way get speed, even if it isn't as readable.d[i]value can be any possible value). Numpy mainly support basic or parallel-like operations (same operation applied on all items). A parallel-like operation is fundamentally less efficient here since it would mean to do more work. That being said, accessing Numpy items from CPython is very inefficient. Numba or Cython can indeed fix that (or any module providing exactly this vectorized function)@nb.njit(...)).