ValueError al verificar si la variable es None o numpy.array

104

Me gustaría comprobar si la variable es None o numpy.array. Implementé una check_afunción para hacer esto.

def check_a(a):
    if not a:
        print "please initialize a"

a = None
check_a(a)
a = np.array([1,2])
check_a(a)

Pero este código genera ValueError. ¿Cuál es la forma más sencilla?

ValueError                                Traceback (most recent call last)
<ipython-input-41-0201c81c185e> in <module>()
      6 check_a(a)
      7 a = np.array([1,2])
----> 8 check_a(a)

<ipython-input-41-0201c81c185e> in check_a(a)
      1 def check_a(a):
----> 2     if not a:
      3         print "please initialize a"
      4 
      5 a = None

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
rkjt50r983
fuente
2
Ésta ValueErrores una de las numpypreguntas más frecuentes . Significa que not aproduce una matriz booleana, con (en este caso) 2 valores. ¡Esta matriz booleana no se puede utilizar como ifcondición! La is Nonealternativa es bueno saber, pero se debe entender también este error.
hpaulj
@hpaulj: No del todo, no puede sobrecargar not, por lo que el error realmente ocurre cuando notintenta tratar la matriz como un solo booleano y descubre que no puede. Si lo hubiera sido ~a, habría usado la sobrecarga de NumPy y habría fallado al ifintentar usar la matriz negada como un único booleano.
user2357112 apoya a Monica

Respuestas:

174

Usar not apara probar si ase Noneasume que los otros valores posibles de atienen un valor de verdad de True. Sin embargo, la mayoría de las matrices NumPy no tienen ningún valor de verdad y notno se pueden aplicar a ellas.

Si desea probar si un objeto lo es None, la forma más general y confiable es usar literalmente una isverificación contra None:

if a is None:
    ...
else:
    ...

Esto no depende de que los objetos tengan un valor de verdad, por lo que funciona con matrices NumPy.

Tenga en cuenta que la prueba tiene que ser is, no ==. ises una prueba de identidad de objeto. ==es lo que los argumentos dicen que es, y las matrices NumPy dicen que es una comparación de igualdad de elementos transmitida, produciendo una matriz booleana:

>>> a = numpy.arange(5)
>>> a == None
array([False, False, False, False, False])
>>> if a == None:
...     pass
...
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()

Por otro lado, si desea probar si un objeto es una matriz NumPy, puede probar su tipo:

# Careful - the type is np.ndarray, not np.array. np.array is a factory function.
if type(a) is np.ndarray:
    ...
else:
    ...

También puede usar isinstance, que también devolverá las Truesubclases de ese tipo (si eso es lo que desea). Teniendo en cuenta lo terrible e incompatible que np.matrixes, es posible que en realidad no desee esto:

# Again, ndarray, not array, because array is a factory function.
if isinstance(a, np.ndarray):
    ...
else:
    ...    
Jerfov2
fuente
4
¿Cuál recomienda que sea la "mejor" solución?
Monica Heddneck
2

Si está intentando hacer algo muy similar a is not None, surge el mismo problema. Es decir, Numpy se queja de que hay que usar a.anyo a.all.

Una solución alternativa es hacer:

if not (a is None):
    pass

No es demasiado bonito, pero funciona.

mimoralea
fuente
0

Puedes ver si el objeto tiene forma o no

def check_array(x):
    try:
        x.shape
        return True
    except:
        return False
Itachi
fuente
1
votado en contra porque: otros tipos pueden tener el atributo de forma también, e incluso pueden tener diferentes significados.
Herbert