6

Using NumPy with Python 2.7, I want to create an n-by-2 array y. Then, I want to check whether this array contains a particular 1-by-2 array z in any of its rows.

Here's what I have tried so far, and in this case, n = 1:

x = np.array([1, 2]) # Create a 1-by-2 array
y = [x] # Create an n-by-2 array (n = 1), and assign the first row to x
z = np.array([1, 2]) # Create another 1-by-2 array
if z in y: # Check if y contains the row z
    print 'yes it is'

However, this gives me the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

What am I doing wrong?

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247

2 Answers2

11

You can do (y == z).all(1).any().

To go into a bit more detail, numpy will element-by-element comparisons across higher dimensions automatically using something called "broadcasting". So if y is your n-by-2 array, and z is your 1-by-2 array, y == z will compare each row of y with z element-by-element. Then you can just use all(axis=1) to get the rows where all elements match, and any() to find out if any match.

So here it is in practice:

>>> y1 = np.array([[1, 2], [1, 3], [1, 2], [2, 2]])
>>> y2 = np.array([[100, 200], [100,300], [100, 200], [200, 200]])
>>> z = np.array([1, 2])
>>>
>>> (y1 == z).all(1).any()
True
>>> (y2 == z).all(1).any()
False

This is considerably faster than doing a loop or generator-based approach since it vectorizes the operation.

TheBlackCat
  • 9,791
  • 3
  • 24
  • 31
7

You can simply use any((z == x).all() for x in y). I don't know if it is the fastest, though.

P. Camilleri
  • 12,664
  • 7
  • 41
  • 76
  • 1
    This will be pretty slow since it doesn't vectorize the code. I tried with `n=10000` and this approach is more than 140 times slower than a vectorized approach. – TheBlackCat Oct 21 '15 at 09:20
  • 1
    Yes, I actually have upvoted your answer and specified that I had doubts about the speed in mine. Nevertheless, the OP had no explicit requirements about speed, so I don't think I should delete my answer; but I think yours should be the one marked as accepted. – P. Camilleri Oct 21 '15 at 09:29