Issue
I just discovered a logical bug in my code which was causing all sorts of problems. I was inadvertently doing a bitwise AND instead of a logical AND.
I changed the code from:
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]
To my surprise, I got the rather cryptic error message:
ValueError: The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()
Why was a similar error not emitted when I use a bitwise operation – and how do I fix this?
Solution
r
is a numpy.recarray
. So r["dt"] >= startdate
is also a (Boolean)
array. For numpy arrays the &
operation returns the elementwise-and of the two Boolean arrays.
The NumPy developers felt there was no one commonly understood way to evaluate an array in Boolean context: it could mean True
if any element is True
, or it could mean True
if all elements are True
, or True
if the array has non-zero length, just to name three possibilities.
Since different users might have different needs and different assumptions, the
NumPy developers refused to guess and instead decided to raise a ValueError
whenever one tries to evaluate an array in Boolean context. Applying and
to two numpy arrays causes the two arrays to be evaluated in Boolean context (by calling __bool__
in Python3 or __nonzero__
in Python2).
Your original code
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
looks correct. However, if you do want and
, then instead of a and b
use (a-b).any()
or (a-b).all()
.
Answered By – unutbu
Answer Checked By – Pedro (BugsFixing Volunteer)