Replace all zeros in vector by previous non-zero value

后端 未结 6 1309
孤独总比滥情好
孤独总比滥情好 2020-12-09 16:31

Matlab/Octave algorithm example:

 input vector: [ 1 0 2 0 7 7 7 0 5 0 0 0 9 ]
output vector: [ 1 1 2 2 7 7 7 7 5 5 5 5 9 ]

The algorithm is

6条回答
  •  离开以前
    2020-12-09 16:58

    I think it is possible, let's start with the basics, you want to capture where number is greater than 0:

     a = [ 1 0 2 0 7 7 7 0 5 0 0 0 9 ] %//Load in Vector
     pada = [a,888];  %//Pad A with a random number at the end to help in case the vector ends with a 0
     b = pada(find(pada >0)); %//Find where number if bigger than 0
     bb = b(:,1:end-1);     %//numbers that are bigger than 0
     c = find (pada==0);   %//Index where numbers are 0
     d = find(pada>0);     %//Index where numbers are greater than 0
     length = d(2:end) - (d(1:end-1));  %//calculate number of repeats needed for each 0 trailing gap.
     %//R = [cell2mat(arrayfun(@(x,nx) repmat(x,1,nx), bb, length,'uniformoutput',0))]; %//Repeat the value
    
     ----------EDIT--------- 
     %// Accumarray and cumsum method, although not as nice as Dan's 1 liner
     t = accumarray(cumsum([1,length])',1);
     R = bb(cumsum(t(1:end-1)));
    

    NOTE: I used arrayfun, but you can use accumarray as well.I think this demonstrates that it is possible to do this in parallel?

    R =
    

    Columns 1 through 10

     1     1     2     2     7     7     7     7     5     5
    

    Columns 11 through 13

     5     5     9
    

    TESTs:

    a = [ 1 0 2 0 7 7 7 0 5 0 0 0 9 0 0 0 ]
    
    R =
    

    Columns 1 through 10

     1     1     2     2     7     7     7     7     5     5
    

    Columns 11 through 16

     5     5     9     9     9     9
    

    PERFORMANCE:

    a = repmat([ 1 0 2 0 7 7 7 0 5 0 0 0 9 ] ,1,10000); %//Double of 130,000
    Arrayfun Method : Elapsed time is 6.840973 seconds.
    AccumArray Method : Elapsed time is 2.097432 seconds.
    

提交回复
热议问题