How To Apply A Function To Each Element Of An Array When The Result Is Dependent Of Preceding Cell
I have an array: a = np.array([2,3,5,8,3,5]) What is the most efficient (vectorized) way to calculate an array where each resulting element is (Pseudocode): result[0] = a[0] for i
Solution 1:
You a looking for Haskell's scanl1
alternative in Python (Haskell example):
Prelude> scanl1 (\ab -> a + (b - a) * 0.5) [2, 3, 5, 8, 3, 5][2.0,2.5,3.75,5.875,4.4375,4.71875]
There is an accumulate
function in itertools
module:
In [1]: import itertools
In [2]: itertools.accumulate([2, 3, 5, 8, 3, 5], lambda a, b: a + (b - a) * 0.5)
Out[2]: <itertools.accumulate at 0x7f1fc1fc1608>
In [3]: list(itertools.accumulate([2, 3, 5, 8, 3, 5], lambda a, b: a + (b - a) * 0.5))
Out[3]: [2, 2.5, 3.75, 5.875, 4.4375, 4.71875]
With NumPy you may use numpy.ufunc.accumulate
function, however, according to this answer, there is a bug in the implementation, that is why we should use a cast. Unfortunately, I'm not very familiar with NumPy, and, probably, there is a better way:
In [9]: import numpy as np
In [10]: uf = np.frompyfunc(lambda a, b: a + (b - a) * 0.5, 2, 1)
In [11]: uf.accumulate([2,3,5,8,3,5], dtype=np.object).astype(np.float)
Out[11]: array([ 2. , 2.5 , 3.75 , 5.875 , 4.4375 , 4.71875])
Solution 2:
I would like to post how the @soon code works, or how to implement it with reduce
:
defscanl(f, v):
return reduce(lambda (l, v1), v:(l+[f(v1, v)], f(v1, v)), v[1:], ([v[0]], v[0]))[0]
>>> scanl(lambda a, b: a + (b - a) * 0.5,[2, 3, 5, 8, 3, 5])
[2, 2.5, 3.75, 5.875, 4.4375, 4.71875]
Its not the best performance nor the cutier one but gives you an idea of how to do it.
Post a Comment for "How To Apply A Function To Each Element Of An Array When The Result Is Dependent Of Preceding Cell"