python pandas dataframe merge anti-join

python - Pandas anti-unirse



dataframe merge (4)

Considere los siguientes marcos de datos

TableA = pd.DataFrame(np.random.rand(4, 3), pd.Index(list(''abcd''), name=''Key''), [''A'', ''B'', ''C'']).reset_index() TableB = pd.DataFrame(np.random.rand(4, 3), pd.Index(list(''aecf''), name=''Key''), [''A'', ''B'', ''C'']).reset_index()

TableA

TableB

Esta es una forma de hacer lo que quieras.

Método 1

# Identify what values are in TableB and not in TableA key_diff = set(TableB.Key).difference(TableA.Key) where_diff = TableB.Key.isin(key_diff) # Slice TableB accordingly and append to TableA TableA.append(TableB[where_diff], ignore_index=True)

Método 2

rows = [] for i, row in TableB.iterrows(): if row.Key not in TableA.Key.values: rows.append(row) pd.concat([TableA.T] + rows, axis=1).T

Sincronización

4 filas con 2 superposiciones

Método 1 es mucho más rápido

10,000 filas 5,000 se superponen

los bucles son malos

Tengo dos tablas y me gustaría agregarlas para que solo se conserven todos los datos de la tabla A y los datos de la tabla B solo se agreguen si su clave es única (los valores clave son únicos en la tabla A y B, sin embargo, en algunos casos, a La clave se producirá tanto en la tabla A como en la B).

Creo que la forma de hacerlo implicará algún tipo de unión de filtrado (anti-join) para obtener los valores de la tabla B que no aparecen en la tabla A y luego agregar las dos tablas.

Estoy familiarizado con R y este es el código que usaría para hacer esto en R.

library("dplyr") ## Filtering join to remove values already in "TableA" from "TableB" FilteredTableB <- anti_join(TableB,TableA, by = "Key") ## Append "FilteredTableB" to "TableA" CombinedTable <- bind_rows(TableA,FilteredTableB)

¿Cómo lograría esto en python?


La respuesta más fácil imaginable:

tableB = pd.concat([tableB, pd.Series(1)], axis=1) mergedTable = tableA.merge(tableB, how="left" on="key") answer = mergedTable[mergedTable.iloc[:,-1].isnull()][tableA.columns.tolist()]

Debería ser el más rápido propuesto también.


Tendrá ambas tablas TableA y TableB modo que ambos objetos DataFrame tienen columnas con valores únicos en sus respectivas tablas, pero algunas columnas pueden tener valores que ocurren simultáneamente (tienen los mismos valores para una fila) en ambas tablas.

Luego, queremos combinar las filas en la TableA con las filas en la TableB que no coinciden con ninguna en la TableA para una columna ''Clave''. El concepto es imaginarlo comparando dos series de longitud variable, y combinando las filas en una serie sA con la otra sB si los valores de sB no coinciden con los de sA . El siguiente código resuelve este ejercicio:

import pandas as pd TableA = pd.DataFrame([[2, 3, 4], [5, 6, 7], [8, 9, 10]]) TableB = pd.DataFrame([[1, 3, 4], [5, 7, 8], [9, 10, 0]]) removeTheseIndexes = [] keyColumnA = TableA.iloc[:,1] # your ''Key'' column here keyColumnB = TableB.iloc[:,1] # same for i in range(0, len(keyColumnA)): firstValue = keyColumnA[i] for j in range(0, len(keyColumnB)): copycat = keyColumnB[j] if firstValue == copycat: removeTheseIndexes.append(j) TableB.drop(removeTheseIndexes, inplace = True) TableA = TableA.append(TableB) TableA = TableA.reset_index(drop=True)

Tenga en cuenta que esto también afecta los datos de TableB . Puede usar inplace=False y reasignarlo a una newTable , luego TableA.append(newTable) alternativa.

# Table A 0 1 2 0 2 3 4 1 5 6 7 2 8 9 10 # Table B 0 1 2 0 1 3 4 1 5 7 8 2 9 10 0 # Set ''Key'' column = 1 # Run the script after the loop # Table A 0 1 2 0 2 3 4 1 5 6 7 2 8 9 10 3 5 7 8 4 9 10 0 # Table B 0 1 2 1 5 7 8 2 9 10 0


Yo tuve el mismo problema. Esta respuesta utilizando how=''outer'' e indicator=True of merge me inspiró a encontrar esta solución:

import pandas as pd import numpy as np TableA = pd.DataFrame(np.random.rand(4, 3), pd.Index(list(''abcd''), name=''Key''), [''A'', ''B'', ''C'']).reset_index() TableB = pd.DataFrame(np.random.rand(4, 3), pd.Index(list(''aecf''), name=''Key''), [''A'', ''B'', ''C'']).reset_index() print(''TableA'', TableA, sep=''/n'') print(''TableB'', TableB, sep=''/n'') TableB_only = pd.merge( TableA, TableB, how=''outer'', on=''Key'', indicator=True, suffixes=(''_foo'','''')).query( ''_merge == "right_only"'') print(''TableB_only'', TableB_only, sep=''/n'') Table_concatenated = pd.concat((TableA, TableB_only), join=''inner'') print(''Table_concatenated'', Table_concatenated, sep=''/n'')

Lo que imprime esta salida:

TableA Key A B C 0 a 0.035548 0.344711 0.860918 1 b 0.640194 0.212250 0.277359 2 c 0.592234 0.113492 0.037444 3 d 0.112271 0.205245 0.227157 TableB Key A B C 0 a 0.754538 0.692902 0.537704 1 e 0.499092 0.864145 0.004559 2 c 0.082087 0.682573 0.421654 3 f 0.768914 0.281617 0.924693 TableB_only Key A_foo B_foo C_foo A B C _merge 4 e NaN NaN NaN 0.499092 0.864145 0.004559 right_only 5 f NaN NaN NaN 0.768914 0.281617 0.924693 right_only Table_concatenated Key A B C 0 a 0.035548 0.344711 0.860918 1 b 0.640194 0.212250 0.277359 2 c 0.592234 0.113492 0.037444 3 d 0.112271 0.205245 0.227157 4 e 0.499092 0.864145 0.004559 5 f 0.768914 0.281617 0.924693