zephyr
zephyr

Reputation: 2332

Vectorizing Matlab replace array values from start to end

I have an array in which I want to replace values at a known set of indices with the value immediately preceding it. As an example, my array might be

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];

and the indices of values to be replaced by previous values might be

y = [2, 3, 8];

I want this replacement to occur from left to right, or else start to finish. That is, the value at index 2 should be replaced by the value at index 1, before the value at index 3 is replaced by the value at index 2. The result using the arrays above should be

[1, 1, 1, 4, 5, 6, 7, 7, 9, 0]

However, if I use the obvious method to achieve this in Matlab, my result is

>> x(y) = x(y-1)

x =

     1     1     2     4     5     6     7     7     9     0

Hopefully you can see that this operation was performed right to left and the value at index 3 was replaced by the value at index 2, then 2 was replaced by 1.

My question is this: Is there some way of achieving my desired result in a simple way, without brute force looping over the arrays or doing something time consuming like reversing the arrays around?

Upvotes: 2

Views: 97

Answers (2)

Daniel
Daniel

Reputation: 36710

Using nancumsum you can achieve a fully vectorized version. Nevertheless, for most cases the solution karakfa provided is probably one to prefer. Only for extreme cases with long sequences in y this code is faster.

c1=[0,diff(y)==1];
c1(c1==0)=nan;
shift=nancumsum(c1,2,4);
y(~isnan(shift))=y(~isnan(shift))-shift(~isnan(shift));
x(y)=x(y-1)

Upvotes: 4

karakfa
karakfa

Reputation: 67467

Well, practically this is a loop but the order is number of consecutive index elements

while ~isequal(x(y),x(y-1))
  x(y)=x(y-1)
end

Upvotes: 7

Related Questions