Replace NaN with nearest numerical value to the left in the same row

3 views (last 30 days)
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

Accepted Answer

Andrei Bobrov
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)

More Answers (2)

Image Analyst
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])

Roger Stafford
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.

Categories

Find more on Numeric Types in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!