Tener problemas para filtrar mi marco de datos de resultados con una or
condición. Quiero que mi resultado df
extraiga todos los var
valores de columna que estén por encima de 0.25 y por debajo de -0.25.
Esta lógica a continuación me da un valor de verdad ambiguo, sin embargo, funciona cuando divido este filtrado en dos operaciones separadas. ¿Que está sucediendo aquí? No estoy seguro de dónde usar el sugerido a.empty(), a.bool(), a.item(),a.any() or a.all()
.
result = result[(result['var']>0.25) or (result['var']<-0.25)]
|
lugar deor
abs(result['var'])>0.25
Respuestas:
Las declaraciones
or
yand
python requierentruth
valores. Parapandas
estos se consideran ambiguos, por lo que debe utilizar operaciones "bit a bit"|
(o) o&
(y):Estos están sobrecargados para este tipo de estructuras de datos para producir el elemento inteligente
or
(oand
).Solo para agregar más explicaciones a esta declaración:
La excepción se produce cuando desea obtener el
bool
de unpandas.Series
:Lo que golpeó fue un lugar donde el operador convirtió implícitamente los operandos a
bool
(usted usóor
pero también sucede paraand
,if
ywhile
):Además de estos 4 estados hay varias funciones de Python que se esconden algunas
bool
llamadas (comoany
,all
,filter
, ...), estos normalmente no son problemáticos conpandas.Series
, pero para lo completo que quería mencionar estos.En su caso, la excepción no es realmente útil, porque no menciona las alternativas correctas . Para
and
yor
puede usar (si desea comparaciones basadas en elementos):numpy.logical_or
:o simplemente el
|
operador:numpy.logical_and
:o simplemente el
&
operador:Si está utilizando los operadores, asegúrese de configurar sus paréntesis correctamente debido a la precedencia del operador .
Hay varias funciones lógicas numpy que deberían funcionar
pandas.Series
.Las alternativas mencionadas en la Excepción son más adecuadas si la encontró al hacer
if
owhile
. En breve explicaré cada uno de estos:Si desea verificar si su Serie está vacía :
Python normalmente interpreta la
len
gth de los contenedores (comolist
,tuple
...) como valor de verdad si no tiene una interpretación booleana explícita. Entonces, si desea la comprobación similar a Python, puede hacer:if x.size
o enif not x.empty
lugar deif x
.Si
Series
contiene uno y solo un valor booleano:Si desea verificar el primer y único elemento de su Serie (como
.bool()
pero funciona incluso para contenidos no booleanos):Si desea verificar si todo o algún artículo es cero, no está vacío o no es falso:
fuente
and
,or
ynot
en Python. Estos operadores usan directamente lo quebool
devuelve los operandos. Y en cierto modo, Pandas / NumPy lo sobrecargó para aumentar elValueError
porque consideran que el valor de verdad de dicha estructura de datos es ambiguo.Para lógica booleana, use
&
y|
.Para ver lo que está sucediendo, obtienes una columna de booleanos para cada comparación, por ej.
Cuando tenga varios criterios, obtendrá varias columnas devueltas. Es por eso que la lógica de unión es ambigua. Usando
and
oor
trata cada columna por separado, por lo que primero debe reducir esa columna a un solo valor booleano. Por ejemplo, para ver si algún valor o todos los valores en cada una de las columnas es Verdadero.Una forma complicada de lograr lo mismo es comprimir todas estas columnas y realizar la lógica adecuada.
Para obtener más detalles, consulte Indización booleana en los documentos.
fuente
Los pandas usan bitwise '&' '|' y cada condición debe estar envuelta en un '()'
Por ejemplo, siguientes trabajos
Pero la misma consulta sin los corchetes adecuados no
fuente
O, alternativamente, puede usar el módulo Operador. Información más detallada está aquí Documentos de Python
fuente
Esta excelente respuesta explica muy bien lo que está sucediendo y brinda una solución. Me gustaría agregar otra solución que podría ser adecuada en casos similares: usando el
query
método:Ver también http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query .
(Algunas pruebas con un marco de datos con el que estoy trabajando actualmente sugieren que este método es un poco más lento que el uso de operadores bit a bit en series de booleanos: 2 ms frente a 870 µs)
Una advertencia : al menos una situación en la que esto no es sencillo es cuando los nombres de columna son expresiones de python. Tenía columnas nombrados
WT_38hph_IP_2
,WT_38hph_input_2
ylog2(WT_38hph_IP_2/WT_38hph_input_2)
y quería realizar la siguiente consulta:"(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
Obtuve la siguiente cascada de excepciones:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
Supongo que esto sucedió porque el analizador de consultas estaba tratando de hacer algo de las dos primeras columnas en lugar de identificar la expresión con el nombre de la tercera columna.
Aquí se propone una posible solución alternativa .
fuente
Encontré el mismo error y me detuve con un marco de datos pyspark durante unos días, pude resolverlo con éxito al completar los valores de na con 0 ya que estaba comparando valores enteros de 2 campos.
fuente