2011-11-03 5 views
6

Le agradecería si alguien me podría ayudar con esto (y explicar lo que está pasando).Numpy: necesita una mano en la comprensión de lo que sucede con el "en" operador

Esto funciona:

>>> from numpy import array 
>>> a = array((2, 1)) 
>>> b = array((3, 3)) 
>>> l = [a, b] 
>>> a in l 
True 

Pero esto no es así:

>>> c = array((2, 1)) 
>>> c in l 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

El comportamiento quisiera replicar es:

>>> x = (2, 1) 
>>> y = (3, 3) 
>>> l2 = [x, y] 
>>> z = (2, 1) 
>>> z in l2 
True 

Tenga en cuenta que lo anterior también funciona con mutable objetos:

>>> x = [2, 1] 
>>> y = [3, 3] 
>>> l2 = [x, y] 
>>> z = [2, 1] 
>>> z in l2 
True 

Por supuesto, sabiendo que:

>>> (a < b).all() 
True 

Probé (y fracasado):

>>> (c in l).all() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

Respuesta

6

Python hace que la elección que bool([False,True]) es True porque (se dice) cualquier lista no Empy tiene valor booleano True.

Numpy toma la decisión de que bool(np.array([False, True])) debe plantear una ValueError. Numpy fue diseñado desde el punto de vista de que algunos usuarios pueden querer saber si cualquier de los elementos de la matriz son verdaderas, mientras que otros pueden querer saber si todo los elementos de la matriz son ciertas. Dado que los usuarios pueden tener deseos conflictivos, NumPy se niega a adivinar. Se plantea una ValueError y sugiere el uso de np.any o np.all (aunque si se desea replicar el comportamiento del pitón similar, tendrá que utilizar len).

Al evaluar c in l, Python compara c con cada elemento de l comenzando con a. Evalúa bool(c==a). Obtenemos bool(np.array([True True])), lo que genera un ValueError (por el motivo descrito anteriormente).

Desde numpy se niega a adivinar, usted tiene que ser específico. Sugiero:

import numpy as np 
a=np.array((2,1)) 
b=np.array((3,3)) 
c=np.array((2,1)) 
l=[a,b] 
print(any(np.all(c==elt) for elt in l)) 
# True 
+0

Muy útil, gracias (+1) ... Todavía no entiendo por qué 'a in l' obtiene un resultado diferente al de' c in l' embargo. En ambos casos, el comando debería probar una matriz numpy en una lista estándar ... ¿cuál es la diferencia que no puedo ver? – mac

+0

@mac: Esa es una gran pregunta, y no sé la respuesta. [Los documentos dicen] (http://docs.python.org/reference/expressions.html#notin), "Para los tipos de lista y tupla, x en y es verdadero si y solo si existe un índice i tal que x == y [i] es verdadero. ", pero' bool (a == l [0]) 'genera un ValueError y aún' a in l' devuelve True. No sé cómo resolver esta (aparente) contradicción. – unutbu

+0

Y para añadir al misterio, 'b en l' plantea una ValueError ... – unutbu

Cuestiones relacionadas