ValueError: значение истинности массива с более чем одним элементом неоднозначно. Использовать.любой() или.все()
Я только что обнаружил логическую ошибку в моем коде, который вызывает всевозможные проблемы. Я непреднамеренно делал побитовое и вместо логические и.
Я изменил код:
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 () или а.все()
почему подобная ошибка не была выдана, когда я использую побитовую операцию - и как это исправить?
3 ответов:
r- это массив numpy (rec). Так чтоr["dt"] >= startdateтакже (логическое) матрица. Для массивов numpy в&операция возвращает поразрядное и двух логические массивы.разработчики NumPy чувствовали, что не было ни одного общепринятого способа оценки массив в логическом контексте: это может означать
Trueесли любой элементTrue, или это может означатьTrueесли все элементыTrueилиTrueесли массив имеет ненулевую длину, просто назовите три возможности.поскольку у разных пользователей могут быть разные потребности и разные предположения, Разработчики NumPy отказались гадать и вместо этого решили поднять ValueError всякий раз, когда кто-то пытается оценить массив в логическом контексте. Применение
andto два массива numpy приводит к тому, что два массива вычисляются в логическом контексте (по звоню__bool__в Python3 или__nonzero__в Python2).ваш исходный код
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate)) selected = r[mask]выглядит правильно. Однако, если вы хотите
and, вместоa and bиспользовать(a-b).any()или(a-b).all().
у меня была такая же проблема (т. е. индексирование с несколькими условиями, здесь это поиск данных в определенном диапазоне дат). Элемент
(a-b).any()или(a-b).all()Кажется, не работает, по крайней мере для меня.в качестве альтернативы я нашел другое решение, которое отлично работает для моей желаемой функциональности (https://stackoverflow.com/questions/12647471/the-truth-value-of-an-array-with-more-than-one-element-is-ambigous-when-trying-t).
вместо использования предложенного выше кода, просто используя
numpy.logical_and(a,b)будет работать. Здесь вы можете переписать код как
selected = r(logical_and(r["dt"] >= startdate, r["dt"] <= enddate))
причина исключения в том, что
наandнеявно называетbool. Сначала на левом операнде и (если левый операндTrue), затем на правый операнд. Так чтоx and yэквивалентноbool(x) and bool(y).boolнаnumpy.ndarray(если он содержит более одного элемента) вызовет исключение, которое вы видели:>>> import numpy as np >>> arr = np.array([1, 2, 3]) >>> bool(arr) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()The
bool()вызов подразумевается вand, но иif,while,or, так что любой из следующих примеры также потерпят неудачу:>>> arr and arr ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() >>> if arr: pass ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() >>> while arr: pass ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() >>> arr or arr ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()в Python есть больше функций и операторов, которые скрывают
boolзвонит, например2 < x < 10- это просто другой способ написания2 < x and x < 10. А тоandбудем называтьbool:bool(2 < x) and bool(x < 10).The элемент-мудрый эквивалентно
andбудетnp.logical_andфункция, аналогично вы могли бы использоватьnp.logical_orкак эквивалентor.для логических массивов-и сравнения типа
<,<=,==,!=,>=и>на массивы NumPy возвращают логические массивы NumPy-вы также можете использовать элемент-мудрый побитового функции (и операторов):np.bitwise_and(&оператор)>>> np.logical_and(arr > 1, arr < 3) array([False, True, False], dtype=bool) >>> np.bitwise_and(arr > 1, arr < 3) array([False, True, False], dtype=bool) >>> (arr > 1) & (arr < 3) array([False, True, False], dtype=bool)и
bitwise_or(|оператор):>>> np.logical_or(arr <= 1, arr >= 3) array([ True, False, True], dtype=bool) >>> np.bitwise_or(arr <= 1, arr >= 3) array([ True, False, True], dtype=bool) >>> (arr <= 1) | (arr >= 3) array([ True, False, True], dtype=bool)полный список логических и двоичных функций можно найти в NumPy документация:
Comments