Saltar al contenido

Pandas/Python: ¿Cómo concatenar dos marcos de datos sin duplicados?

Julio, miembro de este gran equipo, nos hizo el favor de escribir esta reseña porque conoce perfectamente el tema.

Solución:

La forma más sencilla es simplemente hacer la concatenación y luego eliminar los duplicados.

>>> df1
   A  B
0  1  2
1  3  1
>>> df2
   A  B
0  5  6
1  3  1
>>> pandas.concat([df1,df2]).drop_duplicates().reset_index(drop=True)
   A  B
0  1  2
1  3  1
2  5  6

los reset_index(drop=True) es arreglar el índice después de la concat() y drop_duplicates(). Sin él, tendrá un índice de [0,1,0] en vez de [0,1,2]. Esto podría causar problemas para futuras operaciones en este dataframe en el futuro si no se reinicia de inmediato.

En caso de que ya tenga una fila duplicada en el DataFrame A, luego concatenar y luego soltar las filas duplicadas, eliminará las filas del DataFrame A que quizás desee conservar.

En este caso, deberá crear una nueva columna con un recuento acumulativo y luego eliminar los duplicados, todo depende de su caso de uso, pero esto es común en los datos de series temporales.

Aquí hay un ejemplo:

df_1 = pd.DataFrame([
'date':'11/20/2015', 'id':4, 'value':24,
'date':'11/20/2015', 'id':4, 'value':24,
'date':'11/20/2015', 'id':6, 'value':34,])

df_2 = pd.DataFrame([
'date':'11/20/2015', 'id':4, 'value':24,
'date':'11/20/2015', 'id':6, 'value':14,
])


df_1['count'] = df_1.groupby(['date','id','value']).cumcount()
df_2['count'] = df_2.groupby(['date','id','value']).cumcount()

df_tot = pd.concat([df_1,df_2], ignore_index=False)
df_tot = df_tot.drop_duplicates()
df_tot = df_tot.drop(['count'], axis=1)
>>> df_tot

date    id  value
0   11/20/2015  4   24
1   11/20/2015  4   24
2   11/20/2015  6   34
1   11/20/2015  6   14

Me sorprende que pandas no ofrezca una solución nativa para esta tarea. No creo que sea eficiente simplemente descartar los duplicados si trabaja con grandes conjuntos de datos (como sugirió Rian G).

Probablemente sea más eficiente usar conjuntos para encontrar los índices que no se superponen. Luego use la comprensión de listas para traducir de índice a ‘ubicación de fila’ (booleano), que necesita para acceder a las filas usando iloc[,]. A continuación encontrará una función que realiza la tarea. Si no elige una columna específica (col) para comprobar si hay duplicados, se utilizarán los índices, como solicitó. Si elige una columna específica, tenga en cuenta que las entradas duplicadas existentes en ‘a’ permanecerán en el resultado.

import pandas as pd

def append_non_duplicates(a, b, col=None):
    if ((a is not None and type(a) is not pd.core.frame.DataFrame) or (b is not None and type(b) is not pd.core.frame.DataFrame)):
        raise ValueError('a and b must be of type pandas.core.frame.DataFrame.')
    if (a is None):
        return(b)
    if (b is None):
        return(a)
    if(col is not None):
        aind = a.iloc[:,col].values
        bind = b.iloc[:,col].values
    else:
        aind = a.index.values
        bind = b.index.values
    take_rows = list(set(bind)-set(aind))
    take_rows = [i in take_rows for i in bind]
    return(a.append( b.iloc[take_rows,:] ))

# Usage
a = pd.DataFrame([[1,2,3],[1,5,6],[1,12,13]], index=[1000,2000,5000])
b = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], index=[1000,2000,3000])

append_non_duplicates(a,b)
#        0   1   2
# 1000   1   2   3    <- from a
# 2000   1   5   6    <- from a
# 5000   1  12  13    <- from a
# 3000   7   8   9    <- from b

append_non_duplicates(a,b,0)
#       0   1   2
# 1000  1   2   3    <- from a
# 2000  1   5   6    <- from a
# 5000  1  12  13    <- from a
# 2000  4   5   6    <- from b
# 3000  7   8   9    <- from b

Te mostramos reseñas y valoraciones

Nos encantaría que puedieras dar recomendación a esta sección si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *