Replace NaNs with next real value.
Mostrar comentarios más antiguos
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
Respuesta aceptada
Más respuestas (4)
Image Analyst
el 31 de Oct. de 2014
0 votos
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().
Sean de Wolski
el 31 de Oct. de 2014
Editada: Sean de Wolski
el 31 de Oct. de 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 comentarios
yogan Sganzerla
el 25 de Ag. de 2021
Editada: Image Analyst
el 25 de Ag. de 2021
Where was the variable flintmax defined?
Image Analyst
el 25 de Ag. de 2021
per isakson
el 31 de Oct. de 2014
Editada: per isakson
el 31 de Oct. de 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 comentarios
yogan Sganzerla
el 12 de Jul. de 2021
Editada: yogan Sganzerla
el 12 de Jul. de 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
el 12 de Jul. de 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
el 31 de Oct. de 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);
Categorías
Más información sobre NaNs en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!