MATLAB Answers

0

Remove rows that contain NaN

Asked by Christopher Wible on 19 Jun 2019
Latest activity Commented on by Rik
on 19 Jun 2019
I am currently trying to remove all rows that contain a NaN.
In other words, if you are given this input : A = [ 1 5 8; -3 NaN 14; 0 6 NaN]
The output should be: B = [1 5 8]
This is what I have so far, but I keep getting an error saying the ii index cannot exceed 1.
A = [ 1 5 8
-3 NaN 14
0 6 NaN ];
B = remove_nan_rows(A)
function B = remove_nan_rows(A)
[row,column] = size(A);
for ii = 1:row
for jj = 1:column
if isnan(A(ii,jj)) == 1
A(ii,:) = [];
end
end
end
B = A;
end

  0 Comments

Sign in to comment.

1 Answer

Answer by madhan ravi
on 19 Jun 2019

B=A;
B(any(isnan(B),2),:)=[]

  7 Comments

Steven Lord
on 19 Jun 2019
Adam Danz is not quite correct. That indexing expression deletes a row of A. But that itself can be a problem. If you delete rows in a matrix M inside a for loop and the for loop iterates over row numbers (from 1 to size(M, 1)) then you're going to receive an error. In an expression like:
for whichrow = 1:size(M, 1)
% Do something with M(whichrow, :)
end
The value of the upper limit of the iteration is fixed when the for loop starts. So if the matrix originally had 5 rows, whichrow will take on the value 5. If you've deleted row 3 of M when whichrow was 3, when whichrow is 5 the matrix M will only have 4 rows and you'll ask for the 5th row of a 4-row M. That's not going to work.
If you must use a for loop, identify which rows need to be deleted (or kept) in the loop and delete (or keep) them in one logical indexing operation afterwards.
M = magic(4);
nrows = size(M, 1);
toDelete = false(nrows, 1);
toKeep = true(nrows, 1);
for whichrow = 1:nrows
if mod(M(whichrow, 1), 2) == 0
toDelete(whichrow) = true;
toKeep(whichrow) = false;
end
end
M1 = M;
M1(toDelete, :) = []
M2 = M(toKeep, :)
M1 consists of the results of deleting all rows in M whose first element is even. M2 consists of the results of keeping all rows in M whose first element is odd. I created M1 using a copy of M so you can compare the original M and the new M1 and M2.
Of course, you can do the above without the for loop.
M = magic(4);
M3 = M;
M3(mod(M3(:, 1), 2) == 0, :) = []
M4 = M(mod(M(:, 1), 2) ~= 0, :) % not equals (~=) not equals (==)
Adam Danz
on 19 Jun 2019
Yeah, good catch. Also, there are some circumstances where you can remove an element from a matrix such as
a = 1:10;
a(2) = [];
so i'll remove that comment to avoid confusion.
Rik
on 19 Jun 2019
You can also loop backwards
for n=size(A,2):-1:1

Sign in to comment.