ValueError під час перевірки, чи змінною є None, або numpy.array


104

Я хотів би перевірити, чи є змінною None або numpy.array. Я реалізував check_aфункцію для цього.

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

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

Але цей код підвищує ValueError. Який прямий шлях вперед?

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
Це ValueErrorодне з найпоширеніших numpyпитань. Це означає, що not aвиробляє логічний масив з (у цьому випадку) 2 значеннями. Цей булевий масив не можна використовувати як ifумову! is NoneАльтернатива добре знати, але ви повинні також зрозуміти цю помилку.
hpaulj

@hpaulj: Не зовсім - ви не можете перевантажуватися not, тому помилка насправді трапляється, коли notнамагається трактувати масив як єдиний булевий і виявляє, що він не може. Якби це було ~a, це використовувало б перевантаження NumPy і не вдалося, коли ifнамагається використовувати заперечений масив як єдиний булевий.
user2357112 підтримує Моніку

Відповіді:


175

Використання not aдля перевірки aє Noneприпускає , що інші можливі значення aмають значення істинності True. Однак більшість масивів NumPy взагалі не мають значення істинності і notне можуть бути застосовані до них.

Якщо ви хочете перевірити, чи є об'єкт None, найбільш загальним, надійним способом є буквальне використання isперевірки на None:

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

Це не залежить від об'єктів, що мають значення істини, тому він працює з масивами NumPy.

Зауважте, що тест повинен бути is, не ==. isє тестом ідентичності об'єкта. ==незважаючи на те, що аргументи говорять, що це є, і масиви NumPy кажуть, що це трансляція порівняння рівності елементів, що створює булевий масив:

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

З іншого боку, якщо ви хочете перевірити, чи є об’єкт масивом NumPy, ви можете перевірити його тип:

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

Ви також можете використовувати isinstance, що також повернеться Trueдля підкласів цього типу (якщо це те, що ви хочете). Враховуючи, наскільки страшним і несумісним np.matrix, ви насправді цього не хочете:

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

4
яке ви рекомендуєте - це "найкраще" рішення?
Моніка Геднек

2

Якщо ви намагаєтесь зробити щось дуже схоже: a is not Noneз'являється та сама проблема. Тобто, Numpy скаржиться, що треба використовувати a.anyабо a.all.

Вирішення завдання:

if not (a is None):
    pass

Не надто красиво, але це робить свою роботу.


0

Ви можете бачити, чи об’єкт має форму чи ні

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

1
Незважаючи на те, що: і інші типи можуть мати атрибут форми, і вони можуть мати навіть різні значення.
Герберт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.