np.where múltiples declaraciones lógicas pandas

Soy consciente de que hay muchas preguntas sobre el tema de los operadores lógicos encadenados que utilizan np.where.

Tengo 2 marcos de datos:

 df1 ABCDEF Postset 0 1 2 3 4 5 6 yes 1 1 2 3 4 5 6 no 2 1 2 3 4 5 6 yes df2 ABCDEF Preset 0 1 2 3 4 5 6 yes 1 1 2 3 4 5 6 yes 2 1 2 3 4 5 6 yes 

Quiero comparar la singularidad de las filas en cada dataframe. Para hacer esto, necesito verificar que todos los valores sean iguales para un número de columnas seleccionadas.

De esta pregunta : si estoy marcando las columnas a b c d e f puedo hacer:

 np.where((df1.A != df2.A) | (df1.B != df2.B) | (df1.C != df2.C) | (df1.D != df2.D) | (df1.E != df2.E) | (df1.F != df2.F)) 

Lo que correctamente da:

 (array([], dtype=int64),) 

Es decir, los valores en todas las columnas son independientemente iguales para ambos marcos de datos.

Esto está bien para un pequeño dataframe, pero mi dataframe real tiene una gran cantidad de columnas que debo verificar. La condición np.where es demasiado larga para escribir con precisión.

En su lugar, me gustaría poner mis columnas en una lista:

 columns_check_list = ['A','B','C','D','E','F'] 

Y use mi statement np.where para realizar mi comprobación en todas las columnas automáticamente.

Esto obviamente no funciona, pero es el tipo de formulario que estoy buscando. Algo como:

 check = np.where([df[column) != df[column] | for column in columns_check_list]) 

¿Cómo puedo conseguir esto?

Consideraciones:

  • Tengo muchas columnas
  • El formato de mis datos es fijo.
  • Los valores dentro de las columnas pueden contener strings o floats .

Parece que necesita all para verificar si todos los valores son True por fila o any si al menos un valor es True por fila:

 mask= ~(df1[columns_check_list] == df2[columns_check_list]).all(axis=1).values print (mask) [False False False] 

O más legible, gracias IanS :

 mask= (df1[columns_check_list] != df2[columns_check_list]).any(axis=1).values print (mask) [False False False] 

También es posible comparar la numpy array s:

 mask= (df1[columns_check_list].values != df2[columns_check_list].values).any(axis=1) print (mask) [False False False] 

Puede usar el método de reduce np.logical_or s en los valores de la comparación:

 >>> import numpy as np >>> np.logical_or.reduce((df1 != df2).values, axis=1) # along rows array([False, False, False], dtype=bool) # each value represents a row 

Es posible que deba excluir columnas antes de hacer la comparación:

 (df1[include_columns_list] != df2[include_columns_list]).values 

o después:

 (df1 != df2)[include_columns_list].values 

Además de np.logical_or también hay un np.bitwise_or pero si trata con booleanos (y la comparación devuelve una matriz de booleanos) estos son equivalentes.