replace elements of a vector
    69 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Tiina
 el 5 de Dic. de 2011
  
    
    
    
    
    Comentada: rithy vorn
 el 12 de Nov. de 2016
            Hi,
Is there a possibility to replace the zeros in A by the last non zero observation such as this case:
A=[1 0 2 2 8 0 0 0 3 5 7]
B=[1 1 2 2 8 8 8 8 3 5 7]
Thank you
1 comentario
  rithy vorn
 el 12 de Nov. de 2016
				hell0, could it be possible to do like this A=[1,2,3,4,5] to B=[5,4,3,2,1}
Respuesta aceptada
  Sean de Wolski
      
      
 el 5 de Dic. de 2011
        A=[1 0 2 2 8 0 0 0 3 5 7];
B = A; %copy
idx = logical(A); %locations to keep
Anr = A(idx); %locations to keep
idr = cumsum(idx); %where to replace?
idx = ~idx; %only do this once
B(idx) = Anr(idr(idx)) %replace
This will only run into issues if the first element is zero.
1 comentario
Más respuestas (3)
  Fangjun Jiang
      
      
 el 6 de Dic. de 2011
        What's wrong with using a simple, old, straightforward for-loop? Jan will help me prove that it's faster than other approaches.
A=[1 0 2 2 8 0 0 0 3 5 7];
if A(1)==0
    error('invalid data');
end
for k=2:length(A)
    if A(k)==0;
        A(k)=A(k-1);
    end
end
Or an even better solution
A=[1 0 2 2 8 0 0 0 3 5 7];
if A(1)==0
    error('invalid data');
end
Ind=find(A==0);
for k=Ind
    A(k)=A(k-1);
end
3 comentarios
  Fangjun Jiang
      
      
 el 6 de Dic. de 2011
				@Jan, Thank you for backing me up. 
I can think of another improvement. See update.
  Sven
      
 el 5 de Dic. de 2011
        Hi Tiina, try this. It uses find and arrayfun to replace the zero-values of A with the nearest preceding non-zero value:
zeroInds = find(A==0);
repVals = arrayfun(@(ind)A(find(A(1:ind),1,'last')), zeroInds);
A(zeroInds) = repVals;
Note that if the first element of A is a zero, then the question itself hits a problem, but the above works fine in other cases.
5 comentarios
  Jan
      
      
 el 6 de Dic. de 2011
				Rule 3. All the small dots and crumbs, quotes and the tails of curly braces looks like flyspecks when you observe the monitor from a certain distance.
Rule 4. If you are in doubt, they are flyspecks.
  Sven
      
 el 6 de Dic. de 2011
				Rule 5. If you're in a hurry and just copy Walter's comment code, HE WILL make a typo :)
(now *that* was unexpected)
  Jan
      
      
 el 6 de Dic. de 2011
        A = rand(1, 1e6);
A(rand(size(A)) < 0.1) = 0;   % 10% zeros
tic; for i = 1:20; B = F1(A); end; toc
Some timings (Matlab 2009b/64, Win7, Core2Duo):
function A = F1(A)  % ======================================
n = A~=0;
A(~n) = cell2mat(arrayfun(@(x,y)A(x)*ones(1,y-x),...
                 strfind(n,[1, 0]),strfind([n, 1],[0, 1]),'un',0))
20.528223 sec
function A = F2(A)   % ======================================
nonZero = (A ~= 0);
B       = A(nonZero);
A       = B(cumsum(nonZero));
1.198049 sec
function A = F3(A)   % ======================================
idx = logical(A); %locations to keep
Anr = A(idx); %locations to keep
idr = cumsum(idx); %where to replace?
idx = ~idx; %only do this once
A(idx) = Anr(idr(idx)); %replace
1.151062 sec
function A=F4(A)     % ======================================
if A(1)==0
  error('invalid data');
end
for k=2:length(A)
  if A(k)==0
    A(k)=A(k-1);
  end
end
0.615451 sec
#include "mex.h"     // ====================================
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
   double *A;
   mwSize i, n;
   //
   n       = mxGetNumberOfElements(prhs[0]);
   plhs[0] = mxDuplicateArray(prhs[0]);
   A       = mxGetPr(plhs[0]);
   //
   if (A[0] == 0.0) {
      mexErrMsgIdAndTxt("JSimon:FillZeros:BadData", "Input starts with 0.");
   }
   for (i = 0; i < n; i++) {
      if (A[i] == 0.0) {
         A[i] = A[i - 1];
      }
   }
   return;
}
0.210786 sec
The loop ist the fastest Matlab method, because it does not need temporary memory. Another hint to follow the KISS rule: Keep it simply stupid.
But still C is faster in loops.
1 comentario
Ver también
Categorías
				Más información sobre Parallel for-Loops (parfor) en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






