ValueError beim Überprüfen, ob die Variable None oder numpy.array ist


104

Ich möchte überprüfen, ob die Variable None oder numpy.array ist. Ich habe eine check_aFunktion implementiert , um dies zu tun.

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

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

Dieser Code löst jedoch ValueError aus. Was ist der direkte Weg?

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
Dies ValueErrorist eine der häufigsten numpyFragen. not aDies bedeutet, dass ein boolesches Array mit (in diesem Fall) 2 Werten erstellt wird. Dieses boolesche Array kann nicht als ifBedingung verwendet werden! Die is NoneAlternative ist gut zu wissen, aber Sie sollten diesen Fehler auch verstehen.
hpaulj

@hpaulj: Nicht ganz - Sie können nicht überladen not, daher tritt der Fehler tatsächlich auf, wenn notversucht wird, das Array als einen einzelnen Booleschen Wert zu behandeln und herausfindet, dass dies nicht möglich ist. Wenn dies ~ader Fall gewesen wäre, hätte dies die Überladung von NumPy verwendet und wäre fehlgeschlagen, wenn ifversucht wurde, das negierte Array als einzelnen Booleschen Wert zu verwenden.
user2357112 unterstützt Monica

Antworten:


174

Verwenden not a, um zu testen, ob angenommen awird None, dass die anderen möglichen Werte von aeinen Wahrheitswert von haben True. Die meisten NumPy-Arrays haben jedoch überhaupt keinen Wahrheitswert und notkönnen nicht auf sie angewendet werden.

Wenn Sie testen möchten, ob es sich um ein Objekt handelt None, besteht die allgemeinste und zuverlässigste Methode darin, buchstäblich eine isPrüfung gegen Folgendes durchzuführen None:

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

Dies hängt nicht von Objekten mit einem Wahrheitswert ab, daher funktioniert es mit NumPy-Arrays.

Beachten Sie, dass der Test isnicht sein muss ==. isist ein Objektidentitätstest. ==ist, was auch immer die Argumente sagen, und NumPy-Arrays sagen, dass es sich um einen gesendeten elementweisen Gleichheitsvergleich handelt, der ein boolesches Array erzeugt:

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

Wenn Sie andererseits testen möchten, ob ein Objekt ein NumPy-Array ist, können Sie seinen Typ testen:

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

Sie können auch verwenden isinstance, was auch Truefür Unterklassen dieses Typs zurückgegeben wird (wenn Sie dies möchten). In Anbetracht dessen, wie schrecklich und inkompatibel es np.matrixist, möchten Sie dies möglicherweise nicht wirklich:

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

4
Welche empfehlen Sie als "beste" Lösung?
Monica Heddneck

2

Wenn Sie versuchen, etwas sehr Ähnliches zu tun a is not None, tritt das gleiche Problem auf. Das heißt, Numpy beschwert sich, dass man a.anyoder verwenden muss a.all.

Eine Problemumgehung ist zu tun:

if not (a is None):
    pass

Nicht zu hübsch, aber es macht den Job.


0

Sie können sehen, ob das Objekt eine Form hat oder nicht

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

1
herabgestuft, weil: andere Typen auch das Formattribut haben können und sogar andere Bedeutungen haben können.
Herbert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.