This seems to be a very common problem of mine:
data = [1 2 3; 4 5 6];
mask = [true false true];
mask = repmat(mask, 2, 1);
data(mask) ==> [1; 4; 3; 6]
What I wanted was [1 3; 4 6]
.
Yes I can just reshape
it to the right size, but that seems the wrong way to do it. Is there a better way? Why doesn't data(mask)
return a matrix when it is actually rectangular? I understand in the general case it may not be, but in my case since my original mask is an array it always will be.
Corollary
Thanks for the answer, I just also wanted to point out this also works with anything that returns a numeric index like ismember
, sort
, or unique
.
I used to take the second return value from sort
and apply it to every column manually when you can use this notion to do it one shot.
This will give you what you want:
>> data = [1 2 3; 4 5 6];
>> mask = [true false true];
>> data(:,mask)
ans =
1 3
4 6
This works because you can simply apply the logical index mask
to the columns, selecting all the rows with :
.
Even when a 2-D logical array is used for an input, the output will be a column array of indexed values. This is because there is no guarantee that the indexed elements can be organized into a 2-D (i.e. rectangular) output. Consider if your 2-D mask were the following:
mask = [true false true; true false false];
This would index 3 values, which can't be organized into anything but a row or column vector for the output. Here's another example:
mask = [true true true; true false false];
This would index 4 values, but 3 are from the first row and 1 is from the second row. How should these values be shaped into a rectangular output matrix? Since there's no clear way to do this in general for an arbitrary 2-D index matrix, a column vector of indexed values is returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With