mHelpMe
mHelpMe

Reputation: 6668

Indexing into matrix with logical array

I have a matrix A, which is m x n. What I want to do is count the number of NaN elements in a row. If the number of NaN elements is greater than or equal to some arbitrary threshold, then all the values in that row will set to NaN.

num_obs = sum(isnan(rets), 2);
index = num_obs >= min_obs;

Like I say I am struggling to get my brain to work. Being trying different variations of the line below but no luck.

rets(index==0, :) = rets(index==0, :) .* NaN;

The Example data for threshold >= 1 is:

A = [-7 -8 1.6 11.9;
   NaN NaN NaN NaN;
   5.5 6.3 2.1 NaN;
   5.5 4.2 2.2 5.6;
   NaN NaN NaN NaN];

and the result I want is:

A = [-7 -8 1.6 11.9;
   NaN NaN NaN NaN;
   NaN NaN NaN NaN;
   5.5 4.2 2.2 5.6;
   NaN NaN NaN NaN];

Upvotes: 2

Views: 131

Answers (2)

hmofrad
hmofrad

Reputation: 1902

Instead of isnan function, you can use A ~= A for extracting NaN elements.

A(sum((A ~= A),2) >= t,:) = NaN

where t is the threshold for the minimum number of existing NaN elements.

Upvotes: 1

Adriaan
Adriaan

Reputation: 18177

Use

A = magic(4);A(3,3)=nan;
threshold=1;

for ii = 1:size(A,1) % loop over rows
    if sum(isnan(A(ii,:)))>=threshold % get the nans, sum the occurances
        A(ii,:)=nan(1,size(A,2)); % fill the row with column width amount of nans
    end
end

Results in

A =

    16     2     3    13
     5    11    10     8
   NaN   NaN   NaN   NaN
     4    14    15     1

Or, as @Obchardon mentioned in his comment you can vectorise:

A(sum(isnan(A),2)>=threshold,:) = NaN

A =

    16     2     3    13
     5    11    10     8
   NaN   NaN   NaN   NaN
     4    14    15     1

As a side-note you can easily change this to columns, simply do all indexing for the other dimension:

A(:,sum(isnan(A),1)>=threshold) = NaN;

Upvotes: 6

Related Questions