Acabo de descubrir un error lógico en mi código que estaba causando todo tipo de problemas. Inadvertidamente estaba haciendo un AND bit a bit en lugar de un AND lógico .
Cambié el código de:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
A:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]
Para mi sorpresa, recibí el mensaje de error bastante críptico:
ValueError: el valor de verdad de una matriz con más de un elemento es ambiguo. Utilice a.any () o a.all ()
¿Por qué no se emitió un error similar cuando uso una operación bit a bit y cómo lo soluciono?
Respuestas:
r
es una matriz numpy (rec). Tambiénr["dt"] >= startdate
es una matriz (booleana). Para matrices numpy, la&
operación devuelve el elemento -y de las dos matrices booleanas.Los desarrolladores de NumPy sintieron que no había una forma común de evaluar una matriz en un contexto booleano: podría significar
True
si algún elemento esTrue
, o podría significarTrue
si todos los elementos sonTrue
, oTrue
si la matriz tiene una longitud distinta de cero, solo por nombrar tres posibilidadesDado que diferentes usuarios pueden tener diferentes necesidades y diferentes suposiciones, los desarrolladores de NumPy se negaron a adivinar y en su lugar decidieron generar un ValueError cada vez que uno intenta evaluar una matriz en un contexto booleano. La aplicación
and
a dos matrices numpy hace que las dos matrices se evalúen en contexto booleano (llamando__bool__
a Python3 o__nonzero__
Python2).Su código original
parece correcto Sin embargo, si lo desea
and
, entonces en lugar dea and b
usar(a-b).any()
o(a-b).all()
.fuente
np.all
ynp.any
son capaces de cortocircuito, el argumento pasado a él se evalúa antesnp.all
onp.any
tiene la oportunidad de cortocircuito. Para hacerlo mejor, actualmente, tendría que escribir un código C / Cython especializado similar a este .Tuve el mismo problema (es decir, indexar con múltiples condiciones, aquí está encontrando datos en un cierto rango de fechas). El
(a-b).any()
o(a-b).all()
parece que no funciona, al menos para mí.Alternativamente, encontré otra solución que funciona perfectamente para mi funcionalidad deseada ( el valor de verdad de una matriz con más de un elemento es ambiguo cuando intento indexar una matriz ).
En lugar de usar el código sugerido anteriormente, simplemente usar a
numpy.logical_and(a,b)
funcionaría. Aquí es posible que desee volver a escribir el código comofuente
La razón de la excepción es que
and
implícitamente llamabool
. Primero en el operando izquierdo y (si el operando izquierdo esTrue
) luego en el operando derecho. Entoncesx and y
es equivalente abool(x) and bool(y)
.Sin embargo, el
bool
en unnumpy.ndarray
(si contiene más de un elemento) arrojará la excepción que ha visto:La
bool()
llamada está en implícitaand
, sino también enif
,while
,or
, por lo que cualquiera de los siguientes ejemplos también fallará:Hay más funciones y declaraciones en Python que ocultan
bool
llamadas, por ejemplo,2 < x < 10
es solo otra forma de escribir2 < x and x < 10
. Y laand
llamaránbool
:bool(2 < x) and bool(x < 10)
.El equivalente a nivel de elemento para
and
sería lanp.logical_and
función, de forma similar podría usarlonp.logical_or
como equivalente paraor
.Para las matrices booleanas - y comparaciones como
<
,<=
,==
,!=
,>=
y>
en NumPy matrices devuelven tablas de NumPy booleanos - también puede utilizar los elementos en cuanto a nivel de bit funciones (y operadores):np.bitwise_and
(&
operador)y
bitwise_or
(|
operador):Puede encontrar una lista completa de funciones lógicas y binarias en la documentación de NumPy:
fuente
si trabaja con
pandas
lo que resolvió el problema para mí fue que estaba tratando de hacer cálculos cuando tenía valores de NA, la solución era ejecutar:df = df.dropna()
Y después de eso el cálculo que falló.
fuente
Este mensaje de error escrito también se muestra mientras
if-statement
se realiza una comparación donde hay una matriz y, por ejemplo, un bool o int. Ver por ejemplo:Esta cláusula tiene un conjunto de datos como matriz y bool es euhm la "puerta abierta" ...
True
oFalse
.En caso de que la función esté envuelta dentro de un
try-statement
, recibiráexcept Exception as error:
el mensaje sin su tipo de error:fuente
intente esto => numpy.array (r) o numpy.array (yourvariable) seguido del comando para comparar lo que desee.
fuente