0

I'd like to do something like this:

>>> y = np.arange(5)
>>> y in (0, 1, 2)
array([True, True, True, False, False])

This syntax doesn't work. What's the best way to achieve the desired result?

(I'm looking for a general solution. Obviously in this specific case I could do y < 3.)

I'll spell this out a little more clearly for you guys, since at least a few people seem to be confused.

Here is a long way of getting my desired behavior:

new_y = np.empty_like(y)
for i in range(len(y)):
    if y[i] in (0, 1, 2):
        new_y[i] = True
    else:
        new_y[i] = False

I'm looking for this behavior in a more compact form.

Here's another solution:

new_y = np.array([True if item in (0, 1, 2) else False for item in y])

Again, just looking for a simpler way.

1
  • 2
    np.in1d(y, [0,1,2]) Commented Mar 9, 2019 at 20:00

1 Answer 1

2

A good general purpose tool is a broadcasted, or 'outer', comparison between elements of two arrays:

In [35]: y=np.arange(5)                                                         
In [36]: x=np.array([0,1,2])                                                    
In [37]: y[:,None]==x                                                           
Out[37]: 
array([[ True, False, False],
       [False,  True, False],
       [False, False,  True],
       [False, False, False],
       [False, False, False]])

This is doing a fast comparison between every element of y and every element of x. Depending on your needs, you can condense this array along one of the axes:

In [38]: (y[:,None]==x).any(axis=1)                                             
Out[38]: array([ True,  True,  True, False, False])

A comment suggested in1d. I think it's a good idea to look at its code. It has several strategies depending on the relative sizes of the inputs.

In [40]: np.in1d(y,x)                                                           
Out[40]: array([ True,  True,  True, False, False])
In [41]: np.array([True if item in x else False for item in y])                 
Out[41]: array([ True,  True,  True, False, False])

Which is fastest may depend on the size of the inputs. Starting lists your list comprehension might be faster. This pure list version is by far the fastest:

[True if item in (0,1,2) else False for item in (0,1,2,3,4)] 
[item in (0,1,2) for item in (0,1,2,3,4)]    # simpler
Sign up to request clarification or add additional context in comments.

3 Comments

If anyone else ends up here later, and sees the np.in1d comment, probably better to check out np.isin as the modern successor: numpy.org/doc/stable/reference/generated/…
@Starman, but look at its code
I looked at the code, and np.isin just seems to call np.in1d under the hood? github.com/numpy/numpy/blob/v1.24.0/numpy/lib/… Also the np.in1d docs recommend using np.isin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.