user5179049
user5179049

Reputation: 3

how to remove nan values from a matrix keeping matrix size same

I obtained a matrix by doing some calculation.

th1 =

    0.3333    0.6667    0.2500       NaN
    0.5000         0       NaN    0.5000
    0.5000       NaN       NaN       NaN
    0.5000       NaN       NaN       NaN

I have to use this matrix for further calculation, so will these NaN affect my calculation? If so, then how can I remove these keeping the matrix size same?

Upvotes: 0

Views: 2302

Answers (1)

rayryeng
rayryeng

Reputation: 104464

Assuming you want to replace the values in your matrix to some finite number, you can use isnan to help you do that.

Specifically, you can do something like this:

th1(isnan(th1)) = 0;

This will replace all NaN values with 0. However, if you want to remove the NaN values, you can't do this with numeric matrices in MATLAB because MATLAB does not support uneven matrices. Your only option would be a cell array and what you can do is make a cell array where each cell is a row from your matrix.

Specifically, you can do something like this:

th1_out = arrayfun(@(x) th1(x,~isnan(th1(x,:))), 1:size(th1,1), 'uni', 0);

Using your data, we get this:

>> celldisp(th1_out)

th1_out{1} =

    0.3333    0.6667    0.2500



th1_out{2} =

    0.5000         0    0.5000



th1_out{3} =

    0.5000



th1_out{4} =

    0.5000

However, you haven't really told me what calculations you intend to perform. Depending on what calculations you want to perform, you don't even to replace any of the NaN values at all. You can simply ignore them. For example, let's say you wanted to find the average of every row in your matrix. You'd simply count up the total amount of NaN values per row and take that into account when performing your mean.

In other words:

%// Create a temporary input matrix
th1_temp = th1;

%// Used to indicate what is NaN in your array
num_nan = isnan(th1);

%// Set the NaN values to zero in the temporary matrix
th1_temp(num_nan) = 0;

%// Calculate the average per row
average_th1 = sum(th1_temp, 2) ./ (size(th1,1) - sum(num_nan,2));

The logic of the above code is that we indicate what is NaN in your matrix, then if we wanted to find the average of each row, you would create a temporary data matrix that sets the NaN values to zero, then sum over each row and divide by the total number of elements minus those elements that were classified as NaN per row. You subtract by this much because by setting the NaN values to 0, this will not accumulate anything when finding the average, but in order to remove the contribution of these 0 values in your average, you need to subtract by as many NaN values there were per row.

In the Statistics Toolbox, the above code can also be replicated using nanmean but the above code is portable should you not have access to this toolbox.

If you wanted to calculate the average per column, a slight change to the last line of code is all that is required:

%// Calculate the average per column
average_th1 = sum(th1_temp, 1) ./ (size(th1,2) - sum(num_nan,1));

Essentially, I changed the 1s to 2s and the 2s to 1s.

Upvotes: 3

Related Questions