Compruebe si hay valores duplicados en la columna del marco de datos de Pandas

4 minutos de lectura

Avatar de usuario de Jeff Mitchell
jeff mitchell

¿Hay alguna manera en pandas para verificar si una columna de marco de datos tiene valores duplicados, sin realmente eliminar filas? Tengo una función que eliminará filas duplicadas, sin embargo, solo quiero que se ejecute si realmente hay duplicados en una columna específica.

Actualmente comparo la cantidad de valores únicos en la columna con la cantidad de filas: si hay menos valores únicos que filas, entonces hay duplicados y el código se ejecuta.

 if len(df['Student'].unique()) < len(df.index):
    # Code to remove duplicates based on Date column runs

¿Existe una manera más fácil o más eficiente de verificar si existen valores duplicados en una columna específica, usando pandas?

Algunos de los datos de muestra con los que estoy trabajando (solo se muestran dos columnas). Si se encuentran duplicados, otra función identifica qué fila conservar (fila con la fecha más antigua):

    Student Date
0   Joe     December 2017
1   James   January 2018
2   Bob     April 2018
3   Joe     December 2017
4   Jack    February 2018
5   Jack    March 2018

  • ordena tu df por fecha entonces df.drop_duplicates('student')

    – BENY

    8 mayo 2018 a las 22:18


  • @Wen Sí, esto, pero tal vez convertir a fecha y hora y ordenar después. La comprobación rápida sería: any(df['Student'].duplicated())

    – Anton vBR

    8 mayo 2018 a las 22:21


  • Un par de malentendidos: a) nunca es necesario verificar len(df[col].unique())pandas tiene df[col].nunique() b) pero de todos modos ni siquiera necesitas eso, solo estas buscando df[col].duplicated(...)

    – smci

    31 de mayo de 2020 a las 3:09


Avatar de usuario de Anton vBR
Antón vBR

Pregunta principal

¿Hay un valor duplicado en una columna, Verdadero/Falso?

╔═════════╦═══════════════╗
║ Student ║ Date          ║
╠═════════╬═══════════════╣
║ Joe     ║ December 2017 ║
╠═════════╬═══════════════╣
║ Bob     ║ April 2018    ║
╠═════════╬═══════════════╣
║ Joe     ║ December 2018 ║
╚═════════╩═══════════════╝

Suponiendo que el marco de datos anterior (d.f.), podríamos hacer una comprobación rápida si está duplicado en el Student columna por:

boolean = not df["Student"].is_unique      # True (credit to @Carsten)
boolean = df['Student'].duplicated().any() # True

Lecturas adicionales y referencias

Arriba estamos usando uno de los métodos de la Serie Pandas. El Pandas DataFrame tiene varios útiles métodosdos de los cuales son:

  1. soltar_duplicados(uno mismo[, subset, keep, inplace]) – Devuelve DataFrame con filas duplicadas eliminadas, opcionalmente solo considerando ciertas columnas.
  2. duplicado(uno mismo[, subset, keep]) – Devuelve una serie booleana que denota filas duplicadas, opcionalmente solo considerando ciertas columnas.

Estos métodos se pueden aplicar en el DataFrame como un todo, y no solo en una Serie (columna) como se indicó anteriormente. El equivalente sería:

boolean = df.duplicated(subset=['Student']).any() # True
# We were expecting True, as Joe can be seen twice.

Sin embargo, si estamos interesados ​​en el marco completo, podemos seguir adelante y hacer:

boolean = df.duplicated().any() # False
boolean = df.duplicated(subset=['Student','Date']).any() # False
# We were expecting False here - no duplicates row-wise 
# ie. Joe Dec 2017, Joe Dec 2018

Y un último consejo útil. Al usar el keep parámetro normalmente podemos saltarnos algunas filas accediendo directamente a lo que necesitamos:

mantener: {‘primero’, ‘último’, Falso}, predeterminado ‘primero’

  • primero: elimine los duplicados excepto la primera aparición.
  • last : elimina los duplicados excepto la última aparición.
  • Falso: eliminar todos los duplicados.

Ejemplo para jugar

import pandas as pd
import io

data=""'\
Student,Date
Joe,December 2017
Bob,April 2018
Joe,December 2018'''

df = pd.read_csv(io.StringIO(data), sep=',')

# Approach 1: Simple True/False
boolean = df.duplicated(subset=['Student']).any()
print(boolean, end='\n\n') # True

# Approach 2: First store boolean array, check then remove
duplicate_in_student = df.duplicated(subset=['Student'])
if duplicate_in_student.any():
    print(df.loc[~duplicate_in_student], end='\n\n')

# Approach 3: Use drop_duplicates method
df.drop_duplicates(subset=['Student'], inplace=True)
print(df)

Devoluciones

True

  Student           Date
0     Joe  December 2017
1     Bob     April 2018

  Student           Date
0     Joe  December 2017
1     Bob     April 2018

  • Gracias, cualquiera (df[‘Student’].duplicated()) era lo que buscaba.

    –Jeff Mitchell

    8 mayo 2018 a las 23:35


  • Por cierto, no pude hacer funcionar la conversión de fecha (aunque mi función existente funcionó). Recibí el error AttributeError: el objeto ‘DataFrame’ no tiene el atributo ‘Date’ para la línea df[‘Date’] = pd.to_datetime(df.Fecha)

    –Jeff Mitchell

    8 mayo 2018 a las 23:37

  • @JeffMitchell df.Date es igual df['Date']. Es sensible a mayúsculas y minúsculas. ¿Estás seguro de que tus columnas se llaman Fecha? Podría intentar df['Date'] también

    – Anton vBR

    9 de mayo de 2018 a las 8:56


Avatar de usuario de Carsten
Carsten

Puedes usar is_unique:

df['Student'].is_unique

# equals true in case of no duplicates

Se requieren versiones anteriores de pandas:

pd.Series(df['Student']).is_unique

  • solo necesitas hacer df['Student'].is_unique. df['Student'] ya es una serie de pandas

    – Joshlk

    10 de marzo de 2021 a las 9:50

  • Es cierto que las versiones anteriores de pandas sin embargo lucharon con eso. edito la respuesta ahora

    – Carsten

    10 de marzo de 2021 a las 11:01

Si desea saber cuántos duplicados y cuáles son, use:

df.pivot_table(index=['ColumnName'], aggfunc="size")

df.pivot_table(index=['ColumnName1',.., 'ColumnNameN'], aggfunc="size")

Avatar de usuario de Asclepius
Asclepio

Además de DataFrame.duplicated y Series.duplicatedPandas también tiene un DataFrame.any y Series.any.

import pandas as pd

df = pd.read_csv("https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv")

Con Python ≥3.8, busque duplicados y acceda a algunas filas duplicadas:

if (duplicated := df.duplicated(keep=False)).any():
    some_duplicates = df[duplicated].sort_values(by=df.columns.to_list()).head()
    print(f"Dataframe has one or more duplicated rows, for example:\n{some_duplicates}")

¿Ha sido útil esta solución?