Subset array conditional on boolean

Hi, I am trying to subset a 2d array conditional on a boolean.

I can do it using filter and with 1d arrays like:

X = randn(100);
filter(a->a>=0,X)

However, suppose I have something like:

X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0; 
data = [X Y S];

And I want to create two new arrays called data0 and data1 where the first contains X, Y, S when S == 0, and the latter when S == 1. filter doesn’t seem to work. What is the best way to do it?

Hi,
I’m not sure why you would want to save S into your new data matrix, since it will be all 1 or 0
but one thing you could do is the following:

X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0; 
X_greater_0 = X[S]
X_smaller_0 = X[ .!S]

data0 = [ X_greater_0 Y[  S]  ones(100) ]   
data1 = [ X_smaller_0 Y[.!S]  zeros(100)]

The relevant entry in the docs is Logical Indexing.

2 Likes

Thanks Jnaslsensee. I still have some questions though. I implemented your code as

X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0; 

data0 = [ X[ S] Y[  S] ]   
data1 = [ X[ .!S] Y[.!S] ]

I don’t really need S to be in the data matrix, I just put it there. However, I tried doing something like data0 = data[ S] and it didn’t work. What if I have an arbitrarily large number of 1d arrays that I want to subset according to one boolean array, is there any better way to do this rather than `data0 = [A[ S] (…) Z[ S]]?

You could also do the following:

data = [ X Y ]
data0 = data[ S , : ]
data1 = data[ .!S, : ]

This first copies your X and Y into a data matrix.
Then you use the logical indexing ( S ) for the first index and : for the second index, meaning take all.

This introduces a little more copying of data but as long as your code is not performance critical, it shouldn’t be a problem.

2 Likes