How to assign NaN in matrix by masking ?

20 views (last 30 days)
Hello everyone,
I have two matrices, matrix1 is three dimensional 180 x 360 x 12 (latitude x longitute x months) and matrix2 is two dimensional 180 x 360
In matrix one I want to assign NaN in entire matrix excluding some columns and some rows. column and row number found from second matrix using following code:
% mask = 100;
% [x y] = find(matrix2 == mask); %%%%by this I found the x and y coordinates.
Now how can I assign NaN in entire matrix1 excluding x and y coordinates which is found by matrix2 ? Can anyone help in this regard? I'll be thankful.

Accepted Answer

Paxorus Sahay
Paxorus Sahay on 26 Jul 2016
Logical indexing is your friend! find() is a little slow because it can't predict how many matches there will be, so it can't preallocate the output vectors and keeps resizing those vectors every time a new match is found.
The "logical" solution:
matrix1(~(matrix2 == mask)) = nan
(matrix2 == mask) is a boolean matrix, with 1 indicating it matches the mask. The ~ operator flips the 0's and 1's, so 1 indicates it doesn't match the mask. And you can supply this matrix as the indices to matrix1, and assign nan as the scalar.
  1 Comment
NathanM
NathanM on 26 Jul 2016
Edited: NathanM on 26 Jul 2016
The OP has matrix1 as a 3-dimensional array, so I think this solution would only assign NaNs on the matrix
matrix1(:,:,1)
The rest:
matrix1(:,:,2:12)
would be untouched. I think this should be placed in a for loop that steps through the third dimension.

Sign in to comment.

More Answers (2)

Image Analyst
Image Analyst on 27 Jul 2016
Have you tried just standard masking like this with bsxfun():
% Mask the image using bsxfun() function
masked3DArray = bsxfun(@times, image3d, cast(mask2d, 'like', image3d));
You should get nan's in masked3DArray everywhere that mask2d had a nan. And where mask2d did not have a nan, i.e. where mask2d had a 1, masked3DArray should just be the original (1 times the image3d value).

NathanM
NathanM on 26 Jul 2016
Edited: NathanM on 26 Jul 2016
It might be easiest in this case to instantiate a new 180 x 360 x 12 matrix of all NaNs, and just replace the vector at the appropriate row and column with the corresponding vector from the original matrix:
newMatrix = NaN(180,360,12);
newMatrix(x,y,:) = matrix1(x,y,:);
matrix1 = newMatrix
  2 Comments
Paxorus Sahay
Paxorus Sahay on 26 Jul 2016
I think the OP expects more than one occurrence of mask in matrix2. With the solution you have suggested, the OP would have to use find(), then a for-loop through the matches, which would be un-MATLABish.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!