Tengo un marco de datos de pandas que se ve así:

real_value, prediction
'invalid', 'inv'
'invalid', 'neg'
'invalid', 'inv'
'negative', 'neg'
'negative', 'neg'
'negative', 'neg'
'positive', 'pos'
'positive', 'pos'
'positive', 'inv'

Me gustaría seleccionar todas las filas en las que la predicción y el valor real no coinciden, en otras palabras, me gustaría obtener un marco de datos que se vea como :

real_value, prediction
'invalid', 'neg'
'positive', 'inv'

Intenté df.loc[~df.prediction.isin(df.real_value)], pero esto no funciona. Es fácil de seleccionar en función de un valor específico, definido por el usuario, p. df.loc[~df.prediction.isin(['neg'])], pero no puedo encontrar una manera de seleccionar en función de los valores que ocurren dentro de las filas mismas.

¿Cómo obtengo la selección deseada? Gracias

2
NeStack 30 sep. 2019 a las 18:04

3 respuestas

La mejor respuesta

Use la siguiente condición:

df[df['real_value'].str[:3].ne(df['prediction'])]

Salida:

    real_value  prediction
1   invalid     neg
8   positive    inv

ne devuelve No igual a de serie y otra. Esto es en cuanto a elementos. No puede usar isin porque eso requiere un iterable, Series, DataFrame o dict, por lo que no está comparando las columnas real_value y prediction por elementos.

2
lmiguelvargasf 30 sep. 2019 a las 19:07

Espero que esto ayude.

Esto también debería ayudar. Pandas Flexible Wrappers

df.loc[(df.real_value != df.prediction.astype(str).str[:3])]

Esto es probablemente mucho más ordenado y se basa en el comentario de @WenYoBen:

df[df.Prediction.str[:3].ne(df.real_value)]
1
Danny 30 sep. 2019 a las 15:19

También puede hacerlo utilizando una columna de máscara que es un poco más flexible si la duración de su predicción no es siempre la misma (que es lo que suponen las otras respuestas):

df['mask'] = [x[1] in x[0] for x in zip(df['real_value'], df['prediction'])]
print(df.loc[df['mask'] == False].drop('mask', axis=1))

Devoluciones:

  real_value  prediction
1    invalid         neg  
8   positive         inv
1
d_kennetz 30 sep. 2019 a las 15:26
58170585