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