Estoy filtrando filas en un marco de datos por valores en dos columnas.
Por alguna razón, el operador OR se comporta como yo esperaría que el operador AND se comportara y viceversa.
Mi código de prueba:
import pandas as pd
df = pd.DataFrame({'a': range(5), 'b': range(5) })
# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]
print pd.concat([df, df1, df2], axis=1,
keys = [ 'original df', 'using AND (&)', 'using OR (|)',])
Y el resultado:
original df using AND (&) using OR (|)
a b a b a b
0 0 0 0 0 0 0
1 -1 -1 NaN NaN NaN NaN
2 2 2 2 2 2 2
3 -1 3 NaN NaN -1 3
4 4 -1 NaN NaN 4 -1
[5 rows x 6 columns]
Como puede ver, el AND
operador descarta cada fila en la que al menos un valor es igual -1
. Por otro lado, el OR
operador requiere que ambos valores sean iguales -1
para descartarlos. Esperaría exactamente el resultado opuesto. ¿Alguien podría explicar este comportamiento, por favor?
Estoy usando pandas 0.13.1.
python
pandas
boolean-logic
Wojciech Walczak
fuente
fuente
df.query
ypd.eval
parece que encaja bien en este caso de uso. Para obtener información sobre lapd.eval()
familia de funciones, sus características y casos de uso, visite Evaluación de expresión dinámica en pandas usando pd.eval () .Respuestas:
Así es. Recuerde que está escribiendo la condición en términos de lo que desea conservar , no en términos de lo que desea eliminar. Para
df1
:Estás diciendo "mantener las filas en las que
df.a
no es -1 ydf.b
no es -1", que es lo mismo que soltar todas las filas en las que al menos un valor es -1.Para
df2
:Está diciendo "mantener las filas en las que
df.a
odf.b
no es -1", que es lo mismo que soltar filas donde ambos valores son -1.PD: el acceso encadenado como
df['a'][1] = -1
puede meterte en problemas. Es mejor acostumbrarse a usar.loc
y.iloc
.fuente
DataFrame.query()
Funciona muy bien aquí también.df.query('a != -1 or b != -1')
.&
y|
terminanand
yor
?and
yor
tiene una semántica básica de Python que no se puede modificar.&
y|
, por otro lado, tienen métodos especiales correspondientes que controlan su comportamiento. (En las cadenas de consulta, por supuesto, somos libres de aplicar cualquier análisis que deseemos).df[True & False]
falla perodf[(True) & (False)]
tiene éxito (no probado en este ejemplo)Puede usar query () , es decir:
fuente
Una pequeña teoría de la lógica matemática aquí:
"NO a Y NO b" es lo mismo que "NO (a OR b)" , entonces:
"a NO -1 Yb NO -1" es equivalente a "NO (a es -1 O b es -1)" , que es opuesto (Complemento) de "(a es -1 O b es -1)" .
Entonces, si desea un resultado exactamente opuesto, df1 y df2 deberían ser los siguientes:
fuente