20
votes

I am looking for a way to remove the NaN numbers from a matrix in MATLAB efficiently (i.e. without using a for loop)

I will provide a quick example to illustrate what I am trying to achieve:

Say I have a matrix M:

          3.00          1.00
          1.00          3.00
           NaN           NaN
          3.00          3.00
          1.00          1.00
           NaN           NaN
           NaN           NaN
           NaN           NaN
           NaN           NaN
           NaN           NaN

I would like to find a way to change this to

          3.00          1.00
          1.00          3.00
          3.00          3.00
          1.00          1.00

I am currently trying to do this via M(isfinite(M)) but that ends up returning a vector instead of the matrix. Is there a trick to have it return a matrix instead?

5

5 Answers

26
votes

If you have either no NaNs or all NaNs on each row, you can do the removal using:

M(isfinite(M(:, 1)), :)
19
votes

The best way is

M(any(isnan(M),2),:)=[]

which will remove any row that contains at least one NaN.

2
votes

Actually I would like to recommend a slightly different (and more general) approach.

So, in case that you want to ignore (i.e. delete) all the rows where at least one column includes NaN, then just:

M= M(0== sum(isnan(M), 2), :)
1
votes

try my snip function. I wanted to address typical questions like this in one simple function:

B = snip(A,nan)

you can find the function file at

It also works with all other 'x', '0' or whatever elements and takes care of more similar problems.

1
votes

The following function removes NAN from the data for specified dimensions:

function data_out = remove_nan (data_in, remove_dim)
%remove row or col from the data_in if there is a NaN element

% e.g., data_in =[1 2 3 4 NaN; 1 2 3 4 5; 1 2 3 NaN NaN]
% from this data remove col 4 and 5 such that data_out=[ 1 2 3; 1 2 3; 1 2
% 3]

if nargin==1

    col_loc=any(isnan(data_in),1);
    data_in(:,col_loc)=[];
    data_out=data_in;

elseif nargin==2

    if remove_dim=='col'
        %find the cols with nan and remove the colums
        col_loc=any(isnan(data_in),1);
        data_in(:,col_loc)=[];
        data_out=data_in;
    elseif  remove_dim='row'
        %find the rows with nan and remove the rows
        row_loc=any(isnan(data_in),2);
        data_in(row_loc,:)=[];
        data_out=data_in;
    end
else
    error( 'incorrect no of arguments')

end