replace elements of a vector

126 vues (au cours des 30 derniers jours)
Tiina
Tiina le 5 Déc 2011
Commenté : rithy vorn le 12 Nov 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 commentaire
rithy vorn
rithy vorn le 12 Nov 2016
hell0, could it be possible to do like this A=[1,2,3,4,5] to B=[5,4,3,2,1}

Connectez-vous pour commenter.

Réponse acceptée

Sean de Wolski
Sean de Wolski le 5 Déc 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 commentaire
Jan
Jan le 6 Déc 2011
Let me repeat again, that this needs twice as long as Fangjun's loop.

Connectez-vous pour commenter.

Plus de réponses (3)

Fangjun Jiang
Fangjun Jiang le 6 Déc 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 commentaires
Tiina
Tiina le 6 Déc 2011
Thank you works fine.
Fangjun Jiang
Fangjun Jiang le 6 Déc 2011
@Jan, Thank you for backing me up.
I can think of another improvement. See update.

Connectez-vous pour commenter.


Sven
Sven le 5 Déc 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 commentaires
Jan
Jan le 6 Déc 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
Sven le 6 Déc 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)

Connectez-vous pour commenter.


Jan
Jan le 6 Déc 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 commentaire
Fangjun Jiang
Fangjun Jiang le 6 Déc 2011
+1, I'd better learn C!

Connectez-vous pour commenter.

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by