• Tengo una fuente de datos dos. Uno de los datos es antiguo y el otro es la versión actual de los mismos datos.
  • Necesito encontrar las filas new y updated y deleted en estos dos datos.
  • Aquí hay un ejemplo. Updated en un sentido, los valores de cualquier columna se cambian de los datos antiguos.
>>> import pandas as pd
>>> import numpy as np
>>> df1 = pd.DataFrame({'id':[1,2,3,4],'b':[4,np.nan,6,12]})
>>> df2 = pd.DataFrame({'id':[2,1,3,5],'b':[np.nan,40,6,6]})
>>> df1
   id     b
0   1   4.0
1   2   NaN
2   3   6.0
3   4  12.0
>>> df2
   id    b
0   2  NaN
1   1  40.0
2   3  6.0
3   5  6.0
  • aquí id es la clave principal para la tabla.
  • Puedo encontrar fácilmente nuevas filas al comparar la clave principal.
>>> df2[~df2.id.isin(df1.id)]
   id    b
3   5  6.0
  • Pero tengo problemas para encontrar filas actualizadas en una nueva fuente de datos.
  • Intenté seguir
>>>tmp = df1.merge(df2)
>>> df2[(~df2.id.isin(tmp.id)) & (df2.id.isin(df1.id))]
   id     b
1   1  40.0
  • Esto funciona para un caso dado. Pero cuando aplico lo mismo a mi marco de datos original (la forma (97000,58) y dos columnas combinadas forman un PK) no está dando el resultado deseado. Está dando filas que no se actualizan.
  • Mi pregunta es '¿Es esta la forma correcta de lograr esto?'.
  • ¿Cómo puedo mejorar esto?
1
Poojan 23 oct. 2019 a las 20:58

1 respuesta

La mejor respuesta

Obtenga la intersección de los identificadores y simplemente compare usando ==. Esto solo es posible porque tiene marcos de datos con etiquetas idénticas (es decir, los mismos índices, debido a la intersección, y las mismas columnas).

ids = set(df1.id.unique()).intersection(df2.id)
d1 = df1[df1.id.isin(ids)].set_index('id').sort_index()
d2 = df2[df2.id.isin(ids)].set_index('id').sort_index()
comp = (d1 == d2) | (pd.isnull(d1) & pd.isnull(d2))

Que proporciona un marco de datos booleanos con valores True donde los valores son iguales y valores False donde difieren

   id      b
0   1  False
1   2   True
2   3   True
1
rafaelc 23 oct. 2019 a las 18:20