Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if an array is element of a list of arrays

I have 13 python NumPy arrays:

obj_1=np.array([784,785,786,787,788,789,790,791,792])
obj_2=np.array([716,717,718,730,731,732,721,722,724,726,727])
obj_3=np.array([658,659,660,661,662,663,664,665])
obj_4=np.array([581,582,583,589,590,591,595,597,598,599,601,605,606,613,614])
obj_5=np.array([533,534,535,536,537])
obj_6=np.array([464,469,472,474])
obj_7=np.array([406,409,411,412])
obj_8=np.array([345,346,347,349])
obj_9=np.array([277,278,281,282,283,284,288,296])
obj_10=np.array([217,219,220,223,224])
obj_11=np.array([154,155,156,157,158,159,160,161])
obj_12=np.array([91,92,93,94,95,96,97])
obj_13=np.array([28,29,30,31,32,33,34])

Then the following loop:

for i in [obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9, obj_10, obj_11, obj_12, obj_13]:
    print i in [obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9]

I would expect this output:

True
True
True
True
True
True
True
True
True
False
False
False
False

Instead I get the following with an error:

True
True
True
True
True
True
Traceback (most recent call last):

File "<ipython-input-221-c03c1ef308c6>", line 16, in <module>
print i in [obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9]

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

I tested different arrays with the same names and the same for loop; they produced no error.

It seems like the problem lies in the content of the arrays, but I couldn't figure out where.

Does anyone have an idea why this happens?

like image 334
orieger Avatar asked Dec 29 '14 22:12

orieger


1 Answers

When you do obj in list python compares obj for equality with each of the members of list. The problem is that the equality operator in numpy doesn't behave in a consistent way. For example:

>>> obj_3 == obj_6
False

because they have different lengths, a boolean is returned.

>>> obj_7==obj_6
array([False, False, False, False], dtype=bool)

because they have the same length, the arrays are compared element wise and a numpy array is returned. In this case the truth value is undetermined. It looks like this strange behaviour is going to change in the future.

The correct way to do it would be to compare individually each pair of arrays using for example numpy.array_equal:

for i in [obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9, obj_10, obj_11, obj_12, obj_13]:
    print any(np.array_equal(i, j) for j in [obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9])

gets you:

True
True
True
True
True
True
True
True
True
False
False
False
False
like image 161
elyase Avatar answered Oct 04 '22 22:10

elyase