ValueError lors de la vérification si la variable est None ou numpy.array


104

Je voudrais vérifier si la variable est None ou numpy.array. J'ai implémenté une check_afonction pour ce faire.

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

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

Mais, ce code déclenche ValueError. Quelle est la manière la plus simple?

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
C'est l' ValueErrorune des questions les plus courantes numpy. Cela signifie not aproduit un tableau booléen, avec (dans ce cas) 2 valeurs. Ce tableau booléen ne peut pas être utilisé comme ifcondition! L' is Nonealternative est bonne à savoir, mais vous devez également comprendre cette erreur.
hpaulj

@hpaulj: Pas tout à fait - vous ne pouvez pas surcharger not, donc l'erreur se produit en fait lorsque vous essayez notde traiter le tableau comme un seul booléen et qu'il découvre que ce n'est pas le cas. Si cela avait été le cas ~a, cela aurait utilisé la surcharge de NumPy et aurait échoué lorsque vous ifessayez d'utiliser le tableau inversé comme un booléen unique.
user2357112 prend en charge Monica

Réponses:


175

Utiliser not apour tester si aest Nonesuppose que les autres valeurs possibles de aont une valeur de vérité de True. Cependant, la plupart des tableaux NumPy n'ont pas du tout de valeur de vérité et notne peuvent pas leur être appliqués.

Si vous voulez tester si un objet est None, le moyen le plus général et le plus fiable est d'utiliser littéralement une isvérification contre None:

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

Cela ne dépend pas des objets ayant une valeur de vérité, donc cela fonctionne avec les tableaux NumPy.

Notez que le test doit être is, non ==. isest un test d'identité d'objet. ==est ce que les arguments disent que c'est, et les tableaux NumPy disent que c'est une comparaison d'égalité élément par élément diffusée, produisant un tableau booléen:

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

De l'autre côté des choses, si vous souhaitez tester si un objet est un tableau NumPy, vous pouvez tester son type:

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

Vous pouvez également utiliser isinstance, qui retournera également Truepour les sous-classes de ce type (si c'est ce que vous voulez). Compte tenu de la gravité et de l'incompatibilité np.matrix, vous ne voudrez peut-être pas vraiment ceci:

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

4
quelle solution recommandez-vous est la «meilleure» solution?
Monica Heddneck

2

Si vous essayez de faire quelque chose de très similaire:, a is not Nonele même problème se pose. Autrement dit, Numpy se plaint qu'il faut utiliser a.anyou a.all.

Une solution de contournement consiste à faire:

if not (a is None):
    pass

Pas trop joli, mais ça fait le boulot.


0

Vous pouvez voir si l'objet a une forme ou non

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

1
a voté défavorablement parce que: d'autres types peuvent également avoir l'attribut shape, et ils peuvent même avoir des significations différentes.
Herbert
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.