Сравнение с булевыми массивами numpy VS PEP8 E712
PEP8 E712
требует, чтобы "сравнение с True
должно быть if cond is True:
или же if cond:
".
Но если я буду следовать этому PEP8
Я получаю разные / неправильные результаты. Зачем?
In [1]: from pylab import *
In [2]: a = array([True, True, False])
In [3]: where(a == True)
Out[3]: (array([0, 1]),)
# correct results with PEP violation
In [4]: where(a is True)
Out[4]: (array([], dtype=int64),)
# wrong results without PEP violation
In [5]: where(a)
Out[5]: (array([0, 1]),)
# correct results without PEP violation, but not as clear as the first two imho. "Where what?"
2 ответа
Этот совет относится только к if
Заявления проверки на "правдивость" стоимости. numpy
это другой зверь.
>>> a = np.array([True, False])
>>> a == True
array([ True, False], dtype=bool)
>>> a is True
False
Обратите внимание, что a is True
всегда False
так как a
это массив, а не логическое, и is
делает простой тест на равенство ссылок (так только True is True
; None is not True
например).
"True" от Numpy - это не то же самое, что "True" от Python, и поэтому is
терпит неудачу:
>>> import numpy as np
>>> a = np.array([True, True, False])
>>> a[:]
array([ True, True, False], dtype=bool)
>>> a[0]
True
>>> a[0]==True
True
>>> a[0] is True
False
>>> type(a[0])
<type 'numpy.bool_'>
>>> type(True)
<type 'bool'>
Кроме того, в PEP 8 сказано, что НЕ используйте "is" или "==" для логических значений:
Don't compare boolean values to True or False using ==:
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
Пустой массив NumPy действительно тестирует Falsey так же, как пустой список Python или пустой dict:
>>> [bool(x) for x in [[],{},np.array([])]]
[False, False, False]
В отличие от Python, пустой массив из одного элемента Falsey действительно тестирует Falsey:
>>> [bool(x) for x in [[False],[0],{0:False},np.array([False]), np.array([0])]]
[True, True, True, False, False]
Но вы не можете использовать эту логику с массивом с несколькими элементами:
>>> bool(np.array([0,0]))
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()
Таким образом, "дух" PEP 8 с Numpy, вероятно, состоит в том, чтобы проверить только правдивость каждого элемента:
>>> np.where(np.array([0,0]))
(array([], dtype=int64),)
>>> np.where(np.array([0,1]))
(array([1]),)
Или использовать any
:
>>> np.array([0,0]).any()
False
>>> np.array([0,1]).any()
True
И помните, что это не то, что вы ожидаете
>>> bool(np.where(np.array([0,0])))
True
поскольку np.where
возвращает непустой кортеж