-->

Dealing with NaN's in matlab functions

2020-02-07 03:55发布

问题:

I was wondering if matlab has a built in way to deal with NaN's in function calls. More specifically, I am trying to take the mean of a vector that has a NaN in it. For example, in R

> x = c(1,2,3,4,NA)
> mean(x)
[1] NA
> mean(x,na.rm=TRUE)
[1] 2.5

Is there something comprable to this in Matlab that is in one line (I don't want to write my own function nor have to loop to find NaN's before calculating the mean).

Also, I do not have access to the statistics toolbox so I can't use something like nanmean().

回答1:

You could do something like mean(x(~isnan(x))). If you want you could also write a bunch of wrappers like this and put them in your startup.m file.



回答2:

As of MATLAB 2015a, mean supports an extra parameter, nanflag. Using the example from JoErNanO's answer,

A = [1 0 NaN; 0 3 4; 0 NaN 2];
mean(A, 'omitnan')
% = [0.333333333333333 1.5 3]

The default for that parameter is includenan, which will return NaN for columns/rows containing NaNs.

median, cov, min, max, sum, var and std also support ignoring of NaNs.



回答3:

I think this should work:

mean(x(isfinite(x)));


回答4:

What about Matrices?

As Karthik V suggests,

mean(x(~isnan(x)))

will work for vectors. However in case you have an n-by-m matrix and wish to compute the row-/column-wise mean discarding occasional NaN's you will have to run a for loop.

Sample Scenario

Imagine a data matrix of the form:

A = [1 0 NaN; 0 3 4; 0 NaN 2]

A =
 1     0   NaN
 0     3     4
 0   NaN     2

Running mean(A(~isnan(A))) yields:

ans =

1.4286

This is because the logical indexing effectively "flattens" the matrix into a vector.

Looping Solution (Column-wise Mean)

Assuming you want to compute the column-wise mean, the looping solution then becomes:

% Preallocate resulting mean vector
nCols = size(A, 2);
mu = zeros(1, nCols);

% Compute means
for col = 1:nCols
    mu(col) = mean(A(~isnan(A(:, col)), col));
end

Resulting in:

mu =

0.3333    1.5000    3.0000

Looping Solution (Row-wise Mean)

Assuming you want to compute the row-wise mean, the looping solution then becomes:

% Preallocate resulting mean vector
nRows = size(A, 1);
mu = zeros(nRows, 1);

% Compute means
for row = 1:nRows
    mu(row) = mean(A(row, ~isnan(A(row, :))));
end

Resulting in:

mu =

0.5000
2.3333
1.0000