I need to do logical iteration over numpy array, which's values depend on elements of other array. I've written code below for clarifying my problem. Any suggestions to solve this problem without for loop?
Code
a = np.array(['a', 'b', 'a', 'a', 'b', 'a'])
b = np.array([150, 154, 147, 126, 148, 125])
c = np.zeros_like(b)
c[0] = 150
for i in range(1, c.size):
if a[i] == "b":
c[i] = c[i-1]
else:
c[i] = b[i]
Here's an approach using a combination of
np.maximum.accumulate
andnp.where
to create stepped indices that are to be stopped at certain intervals and then simply indexing intob
would give us the desired output.Thus, an implementation would be -
Sample step-by-step run -
If you don't need to wrap around the margin there is a very simply solution:
or equally:
If you want to wrap around the margin (
a[0]=='b'
) then it gets a little more complicated, you either need to useroll
or catch this case first with andif
.You could use a more vectorized approach Like so:
np.where
will take the elements fromnp.roll(c, 1)
if the condition isTrue
or it will take fromb
if the condition isFalse
.np.roll(c, 1)
will "roll" forward all the elements ofc
by 1 so that each element refers toc[i-1]
.These type of operations are what make numpy so invaluable. Looping should be avoided if possible.