Я только что обнаружил логическую ошибку в моем коде, которая вызывала все виды проблем. Я невольно делает побитовое И вместо логического И .
Я изменил код с:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
TO:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]
К моему удивлению, я получил довольно загадочное сообщение об ошибке:
ValueError: Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any () или a.all ()
Почему подобная ошибка не выдается, когда я использую побитовую операцию - и как я могу это исправить?
Ответы:
r
является массивом nume (rec) Тоr["dt"] >= startdate
же самое относится и к (логическому) массиву. Для пустых массивов&
операция возвращает поэлементное и два логических массива.Разработчики NumPy считают, что не существует единого общепринятого способа оценки массива в логическом контексте: это может означать, есть
True
ли какой-либо элементTrue
, или это может означать,True
что все элементы имеютTrue
, илиTrue
если массив имеет ненулевую длину, просто назвать три возможности.Так как у разных пользователей могут быть разные потребности и разные предположения, разработчики NumPy отказались угадывать и вместо этого решили поднять ValueError всякий раз, когда кто-то пытается оценить массив в логическом контексте. Применение
and
к двум пустым массивам приводит к оценке двух массивов в логическом контексте (путем вызова__bool__
в Python3 или__nonzero__
в Python2).Ваш оригинальный код
выглядит правильно. Однако, если вы хотите
and
, то вместоa and b
использования(a-b).any()
или(a-b).all()
.источник
np.all
иnp.any
способны к короткому замыканию, переданный ему аргумент оценивается раньшеnp.all
илиnp.any
имеет шанс на короткое замыкание. Чтобы добиться большего успеха, в настоящее время вам нужно написать специальный код C / Cython, похожий на этот .and
и&
вовсе не одно и то же, и у них даже нет одинакового приоритета.У меня была такая же проблема (то есть индексация с несколькими условиями, здесь она находит данные в определенном диапазоне дат).
(a-b).any()
Или ,(a-b).all()
кажется , не работает, по крайней мере для меня.В качестве альтернативы я нашел другое решение, которое идеально подходит для моей желаемой функциональности ( Истинное значение массива с более чем одним элементом неоднозначно при попытке индексировать массив ).
Вместо того, чтобы использовать предложенный выше код, просто
numpy.logical_and(a,b)
сработает. Здесь вы можете переписать код какисточник
Причиной исключения является то, что
and
неявные вызовыbool
. Сначала в левом операнде и (если левый операндTrue
), затем в правом операнде. Такx and y
эквивалентноbool(x) and bool(y)
.Однако
bool
on onnumpy.ndarray
(если он содержит более одного элемента) выдаст исключение, которое вы видели:bool()
Вызов неявно вand
, но и вif
,while
,or
, так что любой из следующих примеров также не будет:В Python есть больше функций и операторов, которые скрывают
bool
вызовы, например,2 < x < 10
это просто еще один способ написания2 < x and x < 10
. Иand
будем называтьbool
:bool(2 < x) and bool(x < 10)
.Поэлементно эквивалент
and
бы бытьnp.logical_and
функция, так же можно использоватьnp.logical_or
как эквивалент дляor
.Для логических массивов - и сравнению нравится
<
,<=
,==
,!=
,>=
и>
на NumPy массивы возвращают булевы массивы Numpy - вы также можете использовать поэлементно битовые функции (и оператор):np.bitwise_and
(&
оператор)и
bitwise_or
(|
оператор):Полный список логических и двоичных функций можно найти в документации NumPy:
источник
если вы работаете с
pandas
тем, что решило проблему для меня, так это то, что я пытался выполнить вычисления, когда у меня были значения NA, решение было запустить:df = df.dropna()
И после этого расчет не удался.
источник
Это типичное сообщение об ошибке также отображается во время
if-statement
сравнения, где есть массив и, например, bool или int. Смотрите, например:Этот пункт имеет набор данных в виде массива, а bool - это «открытая дверь» ...
True
илиFalse
.Если функция обернута внутри,
try-statement
вы получитеexcept Exception as error:
сообщение без типа ошибки:источник
попробуйте это => numpy.array (r) или numpy.array (yourvariable), а затем команду, чтобы сравнить все, что вы хотите.
источник