简体   繁体   中英

Access to a matrix with indexes from a vector

I have a matrix a(16x3) and a vector b(16x1). b shows how many of the values in the matrix a are valid per row.

a = magic(3)

a =

     8     1     6
     3     5     7
     4     9     2

b = [1;3;2]

b =

     1
     3
     2

What I'm trying to do is setting the invalid values to NaN:

a(:,b+1:end)=NaN

Result is:

a =

     8   NaN   NaN
     3   NaN   NaN
     4   NaN   NaN

But what I would have expected is:

a =

 8   NaN   NaN
 3     5     7
 4     9   NaN

What is wrong here?

Perfect setup for bsxfun with @gt to create a logical mask of those elements and then logically index into a to set them as NaNs -

a(bsxfun(@gt,1:size(a,2),b(:))) = NaN

Sample run for a generic mxn case -

a =
     2     9     7     2     9
     5     7     2     9     5
     7     5     1     3     1
     8     1     6     2     2
b =
     1
     4
     3
     2
a =
     2   NaN   NaN   NaN   NaN
     5     7     2     9   NaN
     7     5     1   NaN   NaN
     8     1   NaN   NaN   NaN

Here, the logical mask was -

>> bsxfun(@gt,1:size(a,2),b(:))
ans =
     0     1     1     1     1
     0     0     0     0     1
     0     0     0     1     1
     0     0     1     1     1

So, the 1s were used to select the elements that were to be set as NaNs and rest of the elements were not to be touched or changed.

You can also use a(~bsxfun(@le,1:size(a,2),b(:))) = NaN for the same effect.

I could come up with an idea,

 a = magic(3);
 b = [1;3;2];

the code:

 a (repmat(b,[1 , 3]) < repmat(1 : 3 , [3 , 1])) = NaN

gives;

 a =

 8   NaN   NaN
 3     5     7
 4     9   NaN

For your matrix sizes it would be,

 a = randi(9,[16 3]); 
 b = randi([0 3],[16 1]);

the code:

 a (repmat(b,[1 , 3]) < repmat(1 : 3 , [16 , 1])) = NaN

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM