Thanks for your suggestions, y'all. It's nice that R2014b has the 'next' and 'previous' options for 1D interpolation. I ended up writing a function to do the job in old 2012b.
Replace NaNs with next real value.
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Chad Greene
le 31 Oct 2014
Commenté : Image Analyst
le 25 Août 2021
How can I replace all NaN values in an array with the next non-NaN value in the array? I have
x = [NaN 1 1 3 NaN NaN 4];
and I'd like to turn x into
x = [1 1 1 3 4 4 4];
The following works, but I'd like to do it with fewer moving parts:
for k = find(isnan(x))
x(k) = x(find(1:length(x)>k & isfinite(x),1,'first'));
end
0 commentaires
Réponse acceptée
Plus de réponses (4)
Image Analyst
le 31 Oct 2014
I wouldn't worry about it. If it works, that way is fine. If you have millions of elements or a 2D image, then there are functions that can do it in the Image Processing Toolbox, like imfill().
0 commentaires
Sean de Wolski
le 31 Oct 2014
Modifié(e) : Sean de Wolski
le 31 Oct 2014
x = [NaN 1 1 3 NaN NaN 4];
idx = isnan(x);
idxnan = find(idx);
idxnotnan = find(~idx);
fillv = interp1([-flintmax idxnotnan],[0 x(idxnotnan)],idxnan,'next');
x(idx) = fillv;
Probably slower and harder to figure out than a for-loop and it requires R2014b; but it's cool!
2 commentaires
yogan Sganzerla
le 25 Août 2021
Modifié(e) : Image Analyst
le 25 Août 2021
Where was the variable flintmax defined?
Image Analyst
le 25 Août 2021
per isakson
le 31 Oct 2014
Modifié(e) : per isakson
le 31 Oct 2014
If   x(end)   is a number
while any( isnan( x ) )
x1 = [ x(2:end), inf ];
x( isnan(x) ) = x1( isnan(x) );
end
or
while any( isnan( x ) )
isn = isnan(x);
x( isn ) = x( [false,isn(1:end-1)] );
end
2 commentaires
yogan Sganzerla
le 12 Juil 2021
Modifié(e) : yogan Sganzerla
le 12 Juil 2021
However, if the vector is like the following, it doesn't work properly.
x = [NaN 1 1 3 NaN NaN 4 NaN NaN NaN];
Where the output will be:
[1 1 1 3 4 4 4 NaN NaN NaN]
and my intentions is to be:
[1 1 1 3 4 4 4 4 4 4].
So repeating the last real value until the end (if the vector just has NaN).
What should I add to reach this output?
Thank you for your attention.
Image Analyst
le 12 Juil 2021
@yogan Sganzerla, try this:
x = [NaN 1 1 3 NaN NaN 4 NaN NaN NaN]
nanIndexes = find(isnan(x))
nonNanIndexes = find(~isnan(x))
% Make any leading nans the first non nan value
if nonNanIndexes(1) ~= 1
x(1:nonNanIndexes(1) - 1) = x(nonNanIndexes(1))
end
% Make any trailing nans the last non nan value
if nonNanIndexes(end) ~= length(x)
x(nonNanIndexes(end) + 1 : end) = x(nonNanIndexes(end))
end
% Now regenerate indexes on the changes vector
nanIndexes = find(isnan(x))
nonNanIndexes = find(~isnan(x))
% Replace nan indexes with last non-nan value just prior to it.
for k = 1 : length(nanIndexes)
thisIndex = nanIndexes(k);
x(thisIndex) = x(thisIndex - 1)
end
Roger Stafford
le 31 Oct 2014
Here's another way:
t = isnan(x);
f1 = find(t);
f2 = find(diff([t,false])==-1)+1;
f3 = zeros(1,length(f1));
f3(find(diff([-1,f1])>1)) = diff([0,f2]);
f3 = cumsum(f3);
x2 = [x,x(end)];
x(f1) = x2(f3);
0 commentaires
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!