ValueError durante il controllo se la variabile è None o numpy.array


104

Vorrei controllare se la variabile è None o numpy.array. Ho implementato la check_afunzione per farlo.

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

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

Ma questo codice genera ValueError. Qual è il modo semplice?

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()

2
Questa ValueErrorè una delle numpydomande più comuni . Significa che not aproduce un array booleano, con (in questo caso) 2 valori. Questo array booleano non può essere utilizzato come ifcondizione! L' is Nonealternativa è buona a sapersi, ma dovresti anche capire questo errore.
hpaulj

@hpaulj: Non proprio - non puoi sovraccaricare not, quindi l'errore si verifica effettivamente quando notcerca di trattare l'array come un singolo booleano e scopre che non può. Se lo fosse stato ~a, ciò avrebbe utilizzato il sovraccarico di NumPy e non sarebbe riuscito quando si ifcerca di utilizzare l'array negato come un singolo booleano.
user2357112 supporta Monica

Risposte:


174

Utilizzare not aper verificare se asi Nonepresume che gli altri possibili valori di aabbiano un valore di verità di True. Tuttavia, la maggior parte degli array NumPy non ha affatto un valore di verità e notnon può essere applicato ad essi.

Se vuoi verificare se un oggetto è None, il modo più generale e affidabile è usare letteralmente un iscontrollo contro None:

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

Questo non dipende dagli oggetti che hanno un valore di verità, quindi funziona con gli array NumPy.

Nota che il test deve essere is, no ==. isè un test di identità dell'oggetto. ==è qualunque cosa dicano gli argomenti, e gli array NumPy dicono che è un confronto di uguaglianza elementwise trasmesso, producendo un array booleano:

>>> 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()

D'altro canto, se vuoi verificare se un oggetto è un array NumPy, puoi testarne il tipo:

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

Puoi anche usare isinstance, che restituirà anche Trueper sottoclassi di quel tipo (se è quello che vuoi). Considerando quanto sia terribile e incompatibile np.matrix, potresti non volerlo davvero:

# Again, ndarray, not array, because array is a factory function.
if isinstance(a, np.ndarray):
    ...
else:
    ...    

4
quale mi consigliate è la soluzione "migliore"?
Monica Heddneck

2

Se stai cercando di fare qualcosa di molto simile a is not None:, si presenta lo stesso problema. Cioè, Numpy si lamenta che si deve usare a.anyo a.all.

Una soluzione alternativa è fare:

if not (a is None):
    pass

Non troppo carino, ma fa il lavoro.


0

Puoi vedere se l'oggetto ha forma o meno

def check_array(x):
    try:
        x.shape
        return True
    except:
        return False

1
downvoted perché: altri tipi possono avere anche l'attributo shape e possono anche avere significati diversi.
Herbert
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.