¿Cómo obtengo una lista de todos los elementos duplicados que usan pandas en Python?

127

Tengo una lista de elementos que probablemente tengan algunos problemas de exportación. Me gustaría obtener una lista de los elementos duplicados para poder compararlos manualmente. Cuando trato de usar el método pandas duplicado , solo devuelve el primer duplicado. ¿Hay alguna forma de obtener todos los duplicados y no solo el primero?

Una pequeña subsección de mi conjunto de datos se ve así:

ID,ENROLLMENT_DATE,TRAINER_MANAGING,TRAINER_OPERATOR,FIRST_VISIT_DATE
1536D,12-Feb-12,"06DA1B3-Lebanon NH",,15-Feb-12
F15D,18-May-12,"06405B2-Lebanon NH",,25-Jul-12
8096,8-Aug-12,"0643D38-Hanover NH","0643D38-Hanover NH",25-Jun-12
A036,1-Apr-12,"06CB8CF-Hanover NH","06CB8CF-Hanover NH",9-Aug-12
8944,19-Feb-12,"06D26AD-Hanover NH",,4-Feb-12
1004E,8-Jun-12,"06388B2-Lebanon NH",,24-Dec-11
11795,3-Jul-12,"0649597-White River VT","0649597-White River VT",30-Mar-12
30D7,11-Nov-12,"06D95A3-Hanover NH","06D95A3-Hanover NH",30-Nov-11
3AE2,21-Feb-12,"06405B2-Lebanon NH",,26-Oct-12
B0FE,17-Feb-12,"06D1B9D-Hartland VT",,16-Feb-12
127A1,11-Dec-11,"064456E-Hanover NH","064456E-Hanover NH",11-Nov-12
161FF,20-Feb-12,"0643D38-Hanover NH","0643D38-Hanover NH",3-Jul-12
A036,30-Nov-11,"063B208-Randolph VT","063B208-Randolph VT",
475B,25-Sep-12,"06D26AD-Hanover NH",,5-Nov-12
151A3,7-Mar-12,"06388B2-Lebanon NH",,16-Nov-12
CA62,3-Jan-12,,,
D31B,18-Dec-11,"06405B2-Lebanon NH",,9-Jan-12
20F5,8-Jul-12,"0669C50-Randolph VT",,3-Feb-12
8096,19-Dec-11,"0649597-White River VT","0649597-White River VT",9-Apr-12
14E48,1-Aug-12,"06D3206-Hanover NH",,
177F8,20-Aug-12,"063B208-Randolph VT","063B208-Randolph VT",5-May-12
553E,11-Oct-12,"06D95A3-Hanover NH","06D95A3-Hanover NH",8-Mar-12
12D5F,18-Jul-12,"0649597-White River VT","0649597-White River VT",2-Nov-12
C6DC,13-Apr-12,"06388B2-Lebanon NH",,
11795,27-Feb-12,"0643D38-Hanover NH","0643D38-Hanover NH",19-Jun-12
17B43,11-Aug-12,,,22-Oct-12
A036,11-Aug-12,"06D3206-Hanover NH",,19-Jun-12

Mi código se ve así actualmente:

df_bigdata_duplicates = df_bigdata[df_bigdata.duplicated(cols='ID')]

Hay un par de elementos duplicados. Pero, cuando uso el código anterior, solo obtengo el primer elemento. En la referencia de API, veo cómo puedo obtener el último elemento, pero me gustaría tenerlos todos para poder inspeccionarlos visualmente para ver por qué obtengo la discrepancia. Entonces, en este ejemplo, me gustaría obtener las tres entradas A036 y las 11795 y cualquier otra entrada duplicada, en lugar de la primera. Cualquier ayuda es muy apreciada.

Grande, guapo
fuente
1
"Duplicados" puede significar varias cosas "En su caso, solo desea considerar los duplicados en una sola columnaID , no las" filas idénticas en varias o todas las columnas ".
smci

Respuestas:

170

Método # 1: imprima todas las filas donde el ID es uno de los ID en duplicado:

>>> import pandas as pd
>>> df = pd.read_csv("dup.csv")
>>> ids = df["ID"]
>>> df[ids.isin(ids[ids.duplicated()])].sort("ID")
       ID ENROLLMENT_DATE        TRAINER_MANAGING        TRAINER_OPERATOR FIRST_VISIT_DATE
24  11795       27-Feb-12      0643D38-Hanover NH      0643D38-Hanover NH        19-Jun-12
6   11795        3-Jul-12  0649597-White River VT  0649597-White River VT        30-Mar-12
18   8096       19-Dec-11  0649597-White River VT  0649597-White River VT         9-Apr-12
2    8096        8-Aug-12      0643D38-Hanover NH      0643D38-Hanover NH        25-Jun-12
12   A036       30-Nov-11     063B208-Randolph VT     063B208-Randolph VT              NaN
3    A036        1-Apr-12      06CB8CF-Hanover NH      06CB8CF-Hanover NH         9-Aug-12
26   A036       11-Aug-12      06D3206-Hanover NH                     NaN        19-Jun-12

pero no pude pensar en una buena manera de evitar que se repita idstantas veces. Prefiero el método # 2: groupbyen la identificación.

>>> pd.concat(g for _, g in df.groupby("ID") if len(g) > 1)
       ID ENROLLMENT_DATE        TRAINER_MANAGING        TRAINER_OPERATOR FIRST_VISIT_DATE
6   11795        3-Jul-12  0649597-White River VT  0649597-White River VT        30-Mar-12
24  11795       27-Feb-12      0643D38-Hanover NH      0643D38-Hanover NH        19-Jun-12
2    8096        8-Aug-12      0643D38-Hanover NH      0643D38-Hanover NH        25-Jun-12
18   8096       19-Dec-11  0649597-White River VT  0649597-White River VT         9-Apr-12
3    A036        1-Apr-12      06CB8CF-Hanover NH      06CB8CF-Hanover NH         9-Aug-12
12   A036       30-Nov-11     063B208-Randolph VT     063B208-Randolph VT              NaN
26   A036       11-Aug-12      06D3206-Hanover NH                     NaN        19-Jun-12
DSM
fuente
11
¡El método # 2 es simplemente perfecto! Muchas gracias.
BigHandsome
4
El método # 2 falla ("No hay objetos para concatenar") si no hay dups
CPBL
4
¿qué g for _ hacer?
user77005
5
@ user77005 es posible que haya descubierto ya, pero para beneficio de todos, se lee así: g for (placeholder, g) in df.groupby('bla') if 'bla'; el guión bajo es un símbolo típico de marcador de posición de un argumento inevitable en el que no queremos usarlo para nada en una expresión de tipo lambda.
stucash
7
Método # 1 tiene que ser actualizado: sortse desaprobó para tramas de datos a favor de cualquiera sort_valueso sort_index relacionados para Q & A
tatlar
138

Con Pandas versión 0.17, puede establecer 'keep = False' en la función duplicada para obtener todos los elementos duplicados.

In [1]: import pandas as pd

In [2]: df = pd.DataFrame(['a','b','c','d','a','b'])

In [3]: df
Out[3]: 
       0
    0  a
    1  b
    2  c
    3  d
    4  a
    5  b

In [4]: df[df.duplicated(keep=False)]
Out[4]: 
       0
    0  a
    1  b
    4  a
    5  b
usuario666
fuente
3
Bingo, ahí está la respuesta. Entonces: str o str o boolean ... extraña elección de API. 'all'sería más lógico e intuitivo en mi opinión.
Jarad
92
df[df.duplicated(['ID'], keep=False)]

le devolverá todas las filas duplicadas.

Según documentación :

mantener: {'primero', 'último', falso}, predeterminado 'primero'

  • primero: Marque los duplicados como Verdaderos excepto por la primera aparición.
  • último: Marque los duplicados como Verdaderos excepto por la última aparición.
  • Falso: marca todos los duplicados como verdaderos.
Kelly ChowChow
fuente
@dreme esto no es sintácticamente correcto, ni funciona. No coincide ']' y tampoco devuelve lo que necesitan. Es más corto, pero está mal.
FinancialRadDeveloper
Vaya, tienes razón @FinancialRadDeveloper, en ambos aspectos. Eliminaré mi comentario. Gracias por detectar el error.
dreme
3
df [df ['ID']. duplicated () == True] Esto devolverá todos los duplicados
Hariprasad
12

Como no puedo comentar, por lo tanto, publico como una respuesta separada

Para encontrar duplicados sobre la base de más de una columna, mencione el nombre de cada columna como se muestra a continuación y le devolverá todas las filas duplicadas establecidas:

df[df[['product_uid', 'product_title', 'user']].duplicated() == True]
Deepak
fuente
10
df[df['ID'].duplicated() == True]

Esto funcionó para mi

Hariprasad
fuente
2
En realidad, no tiene que agregar == True, .duplicated()ya devuelve una matriz bool.
Jakub Wagner
3

Usando un elemento lógico o y configurando el argumento take_last del método pandas duplicado en Verdadero y Falso, puede obtener un conjunto de su marco de datos que incluye todos los duplicados.

df_bigdata_duplicates = 
    df_bigdata[df_bigdata.duplicated(cols='ID', take_last=False) |
               df_bigdata.duplicated(cols='ID', take_last=True)
              ]
Oshbocker
fuente
2

Esto puede no ser una solución a la pregunta, pero para ilustrar ejemplos:

import pandas as pd

df = pd.DataFrame({
    'A': [1,1,3,4],
    'B': [2,2,5,6],
    'C': [3,4,7,6],
})

print(df)
df.duplicated(keep=False)
df.duplicated(['A','B'], keep=False)

Las salidas:

   A  B  C
0  1  2  3
1  1  2  4
2  3  5  7
3  4  6  6

0    False
1    False
2    False
3    False
dtype: bool

0     True
1     True
2    False
3    False
dtype: bool
yoonghm
fuente
2

sort("ID")no parece estar funcionando ahora, parece obsoleto según el documento de clasificación , así que utilícelo sort_values("ID")para ordenar después del filtro duplicado, de la siguiente manera:

df[df.ID.duplicated(keep=False)].sort_values("ID")
Nafeez Quraishi
fuente
2

Para mi base de datos duplicada (keep = False) no funcionó hasta que se ordenó la columna.

data.sort_values(by=['Order ID'], inplace=True)
df = data[data['Order ID'].duplicated(keep=False)]
LetzerWille
fuente
1

df[df.duplicated(['ID'])==True].sort_values('ID')

PREM JILLA
fuente
4
Por favor, ¿puede ampliar su respuesta con una explicación más detallada? Esto será muy útil para comprender. ¡Gracias!
vezunchik
¡Bienvenido a Stack Overflow y gracias por tu contribución! Sería amable si pudiera extender su respuesta con una explicación. Aquí encuentras una guía de Cómo dar una buena respuesta . ¡Gracias!
David