Tengo un dataframe que contiene valores duplicados de acuerdo con dos columnas (A y B):
ABC 1 2 1 1 2 4 2 7 1 3 4 0 3 4 8
Quiero eliminar duplicados manteniendo la fila con el valor máximo en la columna C. Esto llevaría a:
ABC 1 2 4 2 7 1 3 4 8
No puedo averiguar cómo hacer eso. ¿Debo usar drop_duplicates()
, algo más?
Puedes hacerlo usando grupo por:
c_maxes = df.groupby(['A', 'B']).C.transform(max) df = df.loc[df.C == c_maxes]
c_maxes
es una Series
de los valores máximos de C
en cada grupo pero que tiene la misma longitud y el mismo índice que df
. Si no ha utilizado .transform
, la impresión de c_maxes
puede ser una buena idea para ver cómo funciona.
Otro enfoque utilizando drop_duplicates
sería
df.sort('C').drop_duplicates(subset=['A', 'B'], take_last=True)
No estoy seguro de cuál es más eficiente, pero supongo que el primer enfoque, ya que no implica la clasificación.
EDITAR: Desde pandas 0.18
hasta la segunda solución sería
df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last')
o alternativamente,
df.sort_values('C', ascending=False).drop_duplicates(subset=['A', 'B'])
En cualquier caso, la solución groupby
parece tener un rendimiento significativamente mayor:
%timeit -n 10 df.loc[df.groupby(['A', 'B']).C.max == df.C] 10 loops, best of 3: 25.7 ms per loop %timeit -n 10 df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last') 10 loops, best of 3: 101 ms per loop
Creo que Groupby debería trabajar.
df.groupby(['A', 'B']).max()['C']
Si necesita un dataframe, puede encadenar la llamada de índice de reinicio.
df.groupby(['A', 'B']).max()['C'].reset_index()
Puedes hacer esto simplemente usando la función pandas drop duplicados
df.drop_duplicates(['A','B'],keep= 'last')
Puedes hacerlo con drop_duplicates
como quieras
# initialisation d = pd.DataFrame({'A' : [1,1,2,3,3], 'B' : [2,2,7,4,4], 'C' : [1,4,1,0,8]}) d = d.sort_values("C", ascending=False) d = d.drop_duplicates(["A","B"])
Si es importante conseguir el mismo pedido.
d = d.sort_index()