Suelte todas las filas duplicadas en Python Pandas

159

La pandas drop_duplicatesfunción es excelente para "uniquificar" un marco de datos. Sin embargo, uno de los argumentos de palabras clave para pasar es take_last=Trueo take_last=False, aunque me gustaría descartar todas las filas que están duplicadas en un subconjunto de columnas. es posible?

    A   B   C
0   foo 0   A
1   foo 1   A
2   foo 1   B
3   bar 1   A

A modo de ejemplo, me gustaría dejar las filas que coinciden en columnas Ay Cpor lo que este debe caer filas 0 y 1.

Jamie Bull
fuente

Respuestas:

233

Esto es mucho más fácil en pandas ahora con drop_duplicates y el parámetro keep.

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.drop_duplicates(subset=['A', 'C'], keep=False)
Ben
fuente
2
¿Qué pasa si mis columnas no están explícitamente etiquetadas? ¿Cómo selecciono las columnas solo en función de su índice?
Hamman Samuel
2
Tal vez df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)?
Ben
55
podrías intentarlodf.drop_duplicates(subset=[df.columns[0:2]], keep = False)
seeiespi
67

Solo quiero agregar a la respuesta de Ben en drop_duplicates :

keep : {'first', 'last', False}, predeterminado 'first'

  • primero: soltar duplicados, excepto la primera aparición.

  • último: soltar duplicados, excepto la última aparición.

  • Falso: descarta todos los duplicados.

Por lo tanto, configurar keepFalse le dará la respuesta deseada.

DataFrame.drop_duplicates (* args, ** kwargs) Devuelve DataFrame con filas duplicadas eliminadas, opcionalmente solo considerando ciertas columnas

Parámetros: subconjunto: etiqueta de columna o secuencia de etiquetas, opcional Solo considere ciertas columnas para identificar duplicados, por defecto use todas las columnas: {'first', 'last', False}, default 'first' first: Drop duplicates excepto por primera vez último: soltar duplicados, excepto la última aparición. Falso: descarta todos los duplicados. take_last: obsoleto in situ: booleano, predeterminado Falso Ya sea para colocar duplicados en el lugar o para devolver una copia cols: kwargs solo argumento del subconjunto [obsoleto] Devuelve: deduplicado: DataFrame

Jake
fuente
25

Si desea que el resultado se almacene en otro conjunto de datos:

df.drop_duplicates(keep=False)

o

df.drop_duplicates(keep=False, inplace=False)

Si el mismo conjunto de datos necesita ser actualizado:

df.drop_duplicates(keep=False, inplace=True)

Los ejemplos anteriores eliminarán todos los duplicados y mantendrán uno, similar a DISTINCT *SQL

Ramanujam Allam
fuente
11

uso groupbyyfilter

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.groupby(["A", "C"]).filter(lambda df:df.shape[0] == 1)
HYRY
fuente
4

En realidad, soltar las filas 0 y 1 solo requiere (cualquier observación que contenga A y C coincidentes se mantiene):

In [335]:

df['AC']=df.A+df.C
In [336]:

print df.drop_duplicates('C', take_last=True) #this dataset is a special case, in general, one may need to first drop_duplicates by 'c' and then by 'a'.
     A  B  C    AC
2  foo  1  B  fooB
3  bar  1  A  barA

[2 rows x 4 columns]

Pero sospecho que lo que realmente quieres es esto (se mantiene una observación que contiene A y C coincidentes):

In [337]:

print df.drop_duplicates('AC')
     A  B  C    AC
0  foo  0  A  fooA
2  foo  1  B  fooB
3  bar  1  A  barA

[3 rows x 4 columns]

Editar:

Ahora es mucho más claro, por lo tanto:

In [352]:
DG=df.groupby(['A', 'C'])   
print pd.concat([DG.get_group(item) for item, value in DG.groups.items() if len(value)==1])
     A  B  C
2  foo  1  B
3  bar  1  A

[2 rows x 3 columns]
CT Zhu
fuente
1
Si eso fuera lo que quería, simplemente lo usaría df.drop_duplicates(['A','C'])como valor predeterminado para que una observación tome la primera o la última como mencioné en la pregunta, aunque me acabo de dar cuenta de que tenía la palabra clave incorrecta mientras escribía de memoria. Lo que quiero es soltar todas las filas que son idénticas en las columnas de interés (A y C en los datos de ejemplo).
Jamie Bull
-1

Prueba estas varias cosas

df = pd.DataFrame({"A":["foo", "foo", "foo", "bar","foo"], "B":[0,1,1,1,1], "C":["A","A","B","A","A"]})

>>>df.drop_duplicates( "A" , keep='first')

o

>>>df.drop_duplicates( keep='first')

o

>>>df.drop_duplicates( keep='last')
Priyansh gupta
fuente