Replace NaN with nearest numerical value to the left in the same row
3 views (last 30 days)
Show older comments
Miles Stephenson
on 20 May 2016
Edited: Andrei Bobrov
on 21 May 2016
Greetings, I have a matrix with numerical and NaN values. I am searching for a vectorized solution to replace all of the NaN values with the nearest numerical value to the left in the same row.
I am guaranteed the first column will always be completely populated with numerical values.
For example, if I start with this matrix:
8 NaN NaN
3 NaN 7
4 9 NaN
I should end up with this:
8 8 8
3 3 7
4 9 9
I am using the loop below to accomplish this: [~,cols] = size(array);
for col = 2:cols
array(isnan(array(:,col)),col) = array(isnan(array(:,col)),col-1);
end
Does anyone know how I can do this without a loop?
Thanks, Miles
0 Comments
Accepted Answer
Andrei Bobrov
on 21 May 2016
Edited: Andrei Bobrov
on 21 May 2016
lo = ~isnan(z);
m = size(z,1);
out = z(bsxfun(@plus,(cumsum(lo,2)-1)*m,(1:m)'));
out(lo) = z(lo)
0 Comments
More Answers (2)
Image Analyst
on 21 May 2016
This works:
m = [8 NaN NaN
3 NaN 7
4 9 NaN]
nanMap = isnan(m)
m(nanMap) = -inf
mOut = imdilate(m, [1, 1])
mOut = imdilate(mOut, [1, 1])
0 Comments
Roger Stafford
on 21 May 2016
Edited: Roger Stafford
on 21 May 2016
Let A be your original matrix. The following is vectorized but I doubt if it is at all superior to, or even the equal of, your simple for-loop.
B = A.’; % To use ‘find’ we have to convert transpose of A to a column vector
t = [~isnan(B(:));true];
f = find(diff([true;t])~=0); % Now we can use ‘find’
t = cumsum(t+accumarray(f(2:2:end),f(2:2:end)-f(1:2:end-1),size(t)));
A = reshape(B(t(1:end-1)),size(B)).’;
For the above to work properly it is necessary that the left side of each row of A be numerical as promised.
0 Comments
See Also
Categories
Find more on Numeric Types in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!