mygems

Cómo eliminar filas duplicadas de un archivo CSV

La mayoría de los duplicados son dos registros de una persona, uno más nuevo. Así los encuentras y te quedas con el correcto.

Por uos ·

Para líneas duplicadas exactas, conservando el encabezado y el orden original:

awk 'NR==1 || !seen[$0]++' input.csv > deduped.csv

Eso resuelve el caso fácil, y el caso fácil es más raro de lo que parece. La mayoría de los «duplicados» de un archivo de trabajo no son líneas idénticas, sino dos registros de la misma persona con otra capitalización, un espacio al final o un teléfono actualizado. Borrar el equivocado hace perder datos, así que el orden de las operaciones importa: decide qué hace iguales a dos filas, mira en qué se diferencian y solo entonces borra.

Paso uno: define la clave

Un duplicado son dos filas que describen lo mismo. Qué columnas lo establecen es una decisión sobre tus datos, no una propiedad del archivo.

  • Un duplicado de fila completa, con todos los campos idénticos, casi siempre es un error: una importación doble, un trabajo que se volvió a ejecutar, un agregado que corrió dos veces. Se puede eliminar sin riesgo.
  • Un duplicado de clave, mismo email o mismo order_id pero todo lo demás distinto, es una cuestión de datos. Probablemente una de esas filas es más reciente o más completa, y tienes que elegir.

Confundir ambos es la forma típica de perder registros. Deduplicar por name en una lista de clientes borrará sin pestañear a dos personas distintas llamadas James Smith.

Paso dos: cuenta antes de borrar

Nunca ejecutes una deduplicación a ciegas. Mira lo que vas a quitar:

duckdb -c "SELECT email, count(*) n FROM read_csv('input.csv') GROUP BY email HAVING n > 1 ORDER BY n DESC LIMIT 20"

Dos números te dicen si la clave es la correcta. Si los duplicados son un puñado, probablemente son entradas dobles genuinas. Si un tercio del archivo está «duplicado», la clave está mal: estás comparando algo que nunca fue único.

Luego mira un caso concreto completo, que es el paso que todos se saltan:

duckdb -c "SELECT * FROM read_csv('input.csv') WHERE email = '[email protected]'"

Ahí descubres que las dos filas difieren justo en la columna que te importaba.

Paso tres: elige qué fila sobrevive

Cuando sabes que las filas difieren, «eliminar duplicados» se convierte en «quedarse con la correcta». Tres reglas, más o menos en orden de cuántas veces acierta cada una:

Quédate con la más reciente. Si hay una marca de tiempo, normalmente es la respuesta.

duckdb -c "COPY (SELECT * FROM (SELECT *, row_number() OVER (PARTITION BY email ORDER BY updated_at DESC) rn FROM read_csv('input.csv')) WHERE rn = 1) TO 'deduped.csv' (HEADER)"

Quédate con la más completa. Sin marca de tiempo, ordenar por el número de campos no vacíos es un buen sustituto, porque el registro más lleno suele ser el posterior. Ordena por (col_a IS NOT NULL)::INT + (col_b IS NOT NULL)::INT + … y toma la primera.

Combina las dos. A veces cada fila tiene algo que le falta a la otra. Es común y no hay atajo: es un coalesce por columna, y para un conjunto pequeño conviene más hacerlo a mano que automatizarlo mal para uno grande.

Elijas lo que elijas, escribe las filas descartadas en un segundo archivo antes de borrarlas. Una deduplicación que no puedes revertir es una que lamentarás en algún momento de las próximas dos semanas.

Casi duplicados, que son la mayoría

La coincidencia exacta pasa por alto la mayoría de los duplicados reales. Normaliza primero, compara después y conserva los valores originales.

duckdb -c "SELECT lower(trim(email)) k, count(*) n FROM read_csv('input.csv') GROUP BY k HAVING n > 1"

Las normalizaciones a aplicar, más o menos por orden de rendimiento:

  • Mayúsculas y minúsculas. [email protected] y [email protected] son el mismo buzón.
  • Espacios. Los espacios finales de un copiar y pegar son invisibles y muy comunes. trim() quita los iniciales y finales; un replace se encarga de los espacios de no separación que llegan de formularios web.
  • Puntuación en identificadores. Los teléfonos +44 20 7946 0958, 02079460958 y (020) 7946 0958 son un solo número. Quita todo lo que no sea un dígito antes de comparar.
  • Puntos de Gmail y direcciones con plus. [email protected] llega a la misma bandeja que [email protected]. Que cuente como duplicado depende de si estás deduplicando personas o cuentas.

Lo que no debes hacer automáticamente: coincidencia aproximada de nombres. «Jon Smith» y «John Smith» pueden ser la misma persona o dos colegas, y un umbral de similitud que sirve para un archivo no sirve para el siguiente. Genera los pares candidatos, revísalos y luego actúa.

CSV File Viewer - Smart CSViPhone y iPad · Android

El editor SQL y el editor de filtros visuales son las dos mitades de este trabajo: un GROUP BY para encontrar las claves duplicadas y luego un filtro para leer cada fila que comparte una, sin cargar nada antes en una base de datos.

Qué hace

En una hoja de cálculo

Excel y Sheets tienen un comando Quitar duplicados (Remove Duplicates), con una propiedad que conviene conocer antes de usarlo: conserva la primera aparición y borra el resto, sin forma de decir cuál es la primera. El orden en que estuviera la hoja decide qué registro sobrevive.

Así que ordena a propósito antes de ejecutarlo. Ordena por tu marca de tiempo de forma descendente y «conservar la primera» pasa a ser «conservar la más nueva», que suele ser lo que querías.

El otro método en hoja de cálculo, una columna auxiliar con COUNTIF, es más lento pero no destructivo, y te muestra los duplicados en lugar de quitarlos. En un archivo grande también es lo que colgará Excel, porque COUNTIF sobre medio millón de filas es cuadrático.

En el teléfono

La versión realista de esto en un teléfono no es una pasada completa de deduplicación. Es ordenar por la columna que sospechas, desplazarte y ver las repeticiones una junto a otra, que es la forma más rápida de saber si un archivo tiene un problema de duplicados.

Cuando ya las ves, filtrar por una clave y leer las pocas filas que la comparten responde la única pregunta que importa: ¿es el mismo registro o son dos registros que casualmente comparten un campo?

CSV Editor - Smart CSViPhone y iPad

Ordena por cualquier columna como en Excel y luego borra filas con el filtro aplicado sin riesgo: las filas ocultas están protegidas, así que un borrado nunca toca datos fuera del filtro. Deshacer lo cubre todo, y eso es lo que hace razonable trabajar así en un teléfono.

Qué hace

Verificar

Tres números, y deben cuadrar:

wc -l input.csv deduped.csv
duckdb -c "SELECT count(*) rows, count(DISTINCT email) keys FROM read_csv('deduped.csv')"

rows y keys ahora deben ser iguales. Si no lo son, la deduplicación no se aplicó a todos los grupos. Y input − deduped debe ser igual al número de filas que querías quitar, el que contaste en el paso dos. Si quitó más, la clave era más amplia o más estrecha de lo que pensabas, y el archivo de filas descartadas que guardaste es ahora lo que te salva la tarde.

Preguntas

¿Cómo elimino filas duplicadas de un archivo CSV?
Para líneas duplicadas exactas, `awk 'NR==1 || !seen[$0]++' input.csv > deduped.csv` conserva el encabezado y el orden original de las filas. Si los duplicados se definen por una columna clave y no por la fila completa, agrupa primero por esa clave para ver qué borrarías, y luego elige qué fila sobrevive, normalmente la más reciente según la marca de tiempo, en lugar de dejar que lo decida la herramienta.
¿Cómo encuentro duplicados en un CSV antes de borrarlos?
Cuéntalos por clave: `SELECT email, count(*) n FROM read_csv('input.csv') GROUP BY email HAVING n > 1`. Si vuelve una fracción grande del archivo, la clave está mal: estás comparando una columna que nunca fue única. Luego selecciona todas las filas de una clave duplicada y léelas una junto a otra; ahí descubres que las filas difieren en una columna que te importa.
¿Qué fila duplicada debo conservar?
La más reciente, si hay una marca de tiempo. Una ventana row_number() particionada por la clave y ordenada por fecha descendente conserva exactamente una fila por clave. Sin marca de tiempo, la fila más completa es un sustituto razonable. Cuando cada fila tiene algo que le falta a la otra, la respuesta honesta es combinarlas columna por columna en lugar de descartar cualquiera.
¿Por qué Quitar duplicados de Excel borra la fila equivocada?
Porque conserva la primera aparición en el orden actual de la hoja y no ofrece forma de influir en cuál es. Ordena por tu marca de tiempo de forma descendente antes de ejecutarlo, para que «conservar la primera» signifique «conservar la más nueva».
¿Cómo detecto duplicados que no son exactamente idénticos?
Normaliza para comparar conservando los valores originales: minúsculas, quitar espacios y quitar lo que no sea dígito en los teléfonos antes de agrupar. Esas tres cosas atrapan la mayoría de los duplicados reales. La coincidencia aproximada de nombres es lo que no conviene automatizar: «Jon Smith» y «John Smith» pueden ser una persona o dos, y un umbral que sirve para un archivo no sirve para el siguiente.
¿Cómo compruebo que la deduplicación funcionó?
El número de filas de la salida y su número de claves distintas ahora deben ser iguales, y el número de filas quitadas debe coincidir con el que contaste antes de borrar. Escribe antes las filas descartadas en un archivo aparte, porque una deduplicación que no puedes revertir es una que querrás revertir.

uos — Crea CSV Editor y Smart CSV Viewer, y ha borrado la fila equivocada de un par de duplicados las veces suficientes como para anotar las comprobaciones.