Python: ¿Eliminar duplicados en un marco de datos basado en dos combinaciones de columnas?
pandas sorting (3)
Mediante el uso de
np.sort
con
duplicated
df[pd.DataFrame(np.sort(df[[''Name1'',''Name2'']].values,1)).duplicated()]
Out[614]:
Name1 Name2 Value
1 Ale Juan 1
Actuación
df=pd.concat([df]*100000)
%timeit df[pd.DataFrame(np.sort(df[[''Name1'',''Name2'']].values,1)).duplicated()]
10 loops, best of 3: 69.3 ms per loop
%timeit df[~df[[''Name1'', ''Name2'']].apply(frozenset, axis=1).duplicated()]
1 loop, best of 3: 3.72 s per loop
Tengo un marco de datos con 3 columnas en Python:
Name1 Name2 Value
Juan Ale 1
Ale Juan 1
y quisiera eliminar los duplicados basados en las columnas Nombre1 y Nombre2 combinaciones.
En mi ejemplo, ambas filas son iguales (pero están en un orden diferente), y me gustaría eliminar la segunda fila y mantener la primera, por lo que el resultado final debería ser:
Name1 Name2 Value
Juan Ale 1
Cualquier idea será realmente apreciada!
Puede convertir a
frozenset
y usar
pd.DataFrame.duplicated
.
res = df[~df[[''Name1'', ''Name2'']].apply(frozenset, axis=1).duplicated()]
print(res)
Name1 Name2 Value
0 Juan Ale 1
frozenset
es necesario en lugar de
set
ya que el
duplicated
utiliza el hashing para verificar si hay duplicados.
Se escala mejor con columnas que con filas. Para un gran número de filas, use el algoritmo basado en clasificación de @ Wen.
Sé que soy un poco tarde para esta pregunta, pero de todas maneras estoy dando mi contribución :)
También puedes usar
get_dummies
y
add
una buena forma de crear filas hashable
df[~(pd.get_dummies(df.a).add(pd.get_dummies(df.b), fill_value=0)).duplicated()]
Los tiempos no son tan buenos como la respuesta de @ Wen, pero aún es más rápido que
apply
+
frozen_set
df=pd.concat([df]*1000000)
%timeit df[~(pd.get_dummies(df.a).add(pd.get_dummies(df.b), fill_value=0)).duplicated()]
1.8 s ± 85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df[pd.DataFrame(np.sort(df[[''a'',''b'']].values,1)).duplicated()]
1.26 s ± 19 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df[~df[[''a'', ''b'']].apply(frozenset, axis=1).duplicated()]
1min 9s ± 684 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)