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
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:
- soltar_duplicados(uno mismo[, subset, keep, inplace]) – Devuelve DataFrame con filas duplicadas eliminadas, opcionalmente solo considerando ciertas columnas.
- 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 igualdf['Date']
. Es sensible a mayúsculas y minúsculas. ¿Estás seguro de que tus columnas se llaman Fecha? Podría intentardf['Date']
también– Anton vBR
9 de mayo de 2018 a las 8:56
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")
Asclepio
Además de DataFrame.duplicated
y Series.duplicated
Pandas 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}")
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 tienedf[col].nunique()
b) pero de todos modos ni siquiera necesitas eso, solo estas buscandodf[col].duplicated(...)
– smci
31 de mayo de 2020 a las 3:09