5

this is a somewhat basic question from a beginner Numpy user: I have a 2D array of say 5 rows and 2 columns, you can see that as 10 2d-vectors, and I want to test if a given vector is inside the table.

For example :

>>> tableau = array(range(10), dtype = uint8)
>>> tableau.shape = (5,2)
>>> print tableau
[[ 0  1]
 [ 2  3]
 [ 4  5]
 [ 6  7]
 [ 8  9]]
>>> [0, 1] in tableau
True

Last line gives True, but '[0, 2] in tableau' too.

For the moment, I compute if euclidean distance is 0, but I'm sure there's a simpler answer.

Thanks for any help

4
  • Seems to be a duplicate of this question. Commented Feb 25, 2013 at 13:37
  • @Junuxx That's a different question, here the vector must (apparently) match an entire row. Commented Feb 25, 2013 at 13:47
  • @Janne: What makes you think that? The example might have a vector that is as long as the matrix is wide, but question clearly says "I want to test if a given vector is inside the table" which is more general. Commented Feb 25, 2013 at 13:48
  • 1
    @Junuxx The example makes me think that. Commented Feb 25, 2013 at 13:52

3 Answers 3

5

You can perform boolean reduction on the match array:

([0, 1] == tableau).all(axis=1).any()
Sign up to request clarification or add additional context in comments.

5 Comments

@Junuxx it does for me; what are you testing against?
@Junuxx that's the wrong shape; it should be length 3. [0, 1, 2] works; it depends how you're interpreting extending the question.
@ecatmur: Yes, it seems I interpreted the question (and "subarray") differently, the question could have been clearer. Asker seems happy though, so this must be right, +1.
I'm happy indeed :) I agree the question is ambiguous, sorry for that.
I posted another answer that builds on yours.
1

Straight forward, you could use any() to go through a generator comparing the arrays with array_equal.

from numpy import array_equal

in_t = lambda x, t : any((array_equal(a,x) for a in t))

print in_t([0, 2], tableau)
print in_t([0, 1], tableau)

Comments

0

I wrote a function to solve this that also handles multidimensional cases. (@ecatmur's answer works perfectly in two dimensions, but fails for 1D or 3D+)

import numpy as np
def haselement(arr,subarr):
    '''Test if subarr is equal to one of the elements of arr.
       This is the equivalent of the "in" operator when using lists instead of arrays.'''
    arr = np.asarray(arr)
    subarr = np.asarray(subarr)
    if subarr.shape!=arr.shape[1:]:
        return False
    elif arr.ndim<2:
        return (subarr==arr).any()
    else:
        boolArr = (subarr==arr)
        boolArr.resize([arr.shape[0],np.prod(arr.shape[1:])])
        return boolArr.all(axis=1).any()

tableau = np.array(range(10), dtype = np.uint8)
tableau.shape = (5,2)
haselement(tableau,[0,1])

1D is handled with an if statement, and ND is handled by resizing the array to 2D so that @ecatmur's algorithm will work. The other ways I thought of to solve this involved list comprehensions or loops (which could actually be more efficient but only if the list is long and the element is near the beginning); still, this seems more numpy-thonic.

You can also find the function here if you'd rather use it from a library:

https://github.com/davidmashburn/np_utils (obvious disclaimer, I am the author ;) )

1 Comment

By the way, does haselement(arr,subarr) or elementof(subarr,arr) make more sense to people? Thanks.

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.