mygems

Comment supprimer les lignes en double d'un fichier CSV

Les doublons sont souvent deux enregistrements d'une même personne, dont un plus récent. Voici comment les trouver et garder le bon.

Par uos ·

Pour les lignes strictement identiques, en gardant l'en-tête et l'ordre d'origine :

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

Cela règle le cas facile, et le cas facile est plus rare qu'il n'en a l'air. La plupart des « doublons » d'un fichier de travail ne sont pas des lignes identiques, mais deux enregistrements de la même personne avec une casse différente, une espace en fin de champ ou un numéro de téléphone mis à jour. Supprimer le mauvais, c'est perdre des données ; l'ordre des opérations compte donc : décidez ce qui rend deux lignes identiques, regardez ce qui les différencie, et seulement ensuite supprimez.

Étape un : définir la clé

Un doublon, ce sont deux lignes qui décrivent la même chose. Les colonnes qui l'établissent relèvent d'une décision sur vos données, pas d'une propriété du fichier.

  • Un doublon de ligne entière, tous les champs identiques, est presque toujours une erreur : un double import, une tâche relancée, un ajout exécuté deux fois. Vous pouvez le supprimer sans risque.
  • Un doublon de clé, même email ou même order_id mais tout le reste différent, est une question de données. L'une des lignes est probablement plus récente ou plus complète, et c'est à vous de choisir.

Inverser les deux est la façon classique de perdre des enregistrements. Dédoublonner sur name dans une liste de clients supprimera sans état d'âme deux personnes différentes qui s'appellent James Smith.

Étape deux : compter avant de supprimer

Ne lancez jamais un dédoublonnage à l'aveugle. Regardez ce que vous allez retirer :

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

Deux chiffres vous disent si votre clé est la bonne. Si le nombre de doublons se compte sur les doigts, ce sont sans doute de vraies saisies en double. Si un tiers du fichier est « dupliqué », la clé est mauvaise : vous comparez quelque chose qui n'a jamais été unique.

Regardez ensuite un cas précis en entier, l'étape que tout le monde saute :

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

C'est là que vous découvrez que les deux lignes diffèrent justement dans la colonne qui vous importait.

Étape trois : choisir la ligne qui reste

Quand vous savez que les lignes diffèrent, « supprimer les doublons » devient « garder la bonne ». Trois règles, à peu près classées selon la fréquence où elles sont justes :

Garder la plus récente. S'il y a un horodatage, c'est généralement la réponse.

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)"

Garder la plus complète. Sans horodatage, trier selon le nombre de champs non vides est un bon substitut, car l'enregistrement le plus rempli est souvent le plus tardif. Triez par (col_a IS NOT NULL)::INT + (col_b IS NOT NULL)::INT + … et prenez la première.

Fusionner les deux. Parfois chaque ligne contient ce qui manque à l'autre. C'est courant et il n'y a pas de raccourci : c'est un coalesce par colonne, et pour un petit ensemble mieux vaut le faire à la main que de mal automatiser pour un gros.

Quel que soit votre choix, écrivez les lignes écartées dans un second fichier avant de les supprimer. Un dédoublonnage irréversible, vous le regretterez à un moment ou à un autre dans les quinze jours qui suivent.

Les quasi-doublons, c'est-à-dire presque tous

La correspondance exacte rate la majorité des doublons réels. Normalisez d'abord, comparez ensuite, et conservez les valeurs d'origine.

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

Les normalisations à appliquer, à peu près par ordre de rendement :

  • La casse. [email protected] et [email protected] sont la même boîte mail.
  • Les espaces. Les espaces en fin de champ venus d'un copier-coller sont invisibles et extrêmement fréquents. trim() retire ceux du début et de la fin ; un replace traite les espaces insécables qui arrivent des formulaires web.
  • La ponctuation dans les identifiants. Les numéros +44 20 7946 0958, 02079460958 et (020) 7946 0958 sont un seul numéro. Supprimez tout ce qui n'est pas un chiffre avant de comparer.
  • Les points Gmail et les adresses avec plus. [email protected] arrive dans la même boîte que [email protected]. Que ce soit un doublon dépend de ce que vous dédoublonnez : des personnes ou des comptes.

Ce qu'il ne faut pas faire automatiquement : la correspondance floue sur les noms. « Jon Smith » et « John Smith » peuvent être la même personne ou deux collègues, et un seuil de similarité adapté à un fichier est mauvais pour le suivant. Générez les paires candidates, relisez-les, puis agissez.

CSV File Viewer - Smart CSViPhone et iPad · Android

L'éditeur SQL et l'éditeur de filtres visuels forment les deux moitiés de ce travail : un GROUP BY pour trouver les clés en double, puis un filtre pour lire chaque ligne qui en partage une, sans rien charger au préalable dans une base de données.

Ce que ça fait

Dans un tableur

Excel et Sheets ont tous deux une commande Supprimer les doublons (Remove Duplicates), avec une particularité à connaître avant de l'utiliser : elle garde la première occurrence et supprime le reste, sans moyen de dire laquelle est la première. L'ordre dans lequel se trouvait la feuille décide quel enregistrement survit.

Triez donc délibérément avant de l'exécuter. Triez par horodatage décroissant, et « garder la première » devient « garder la plus récente », ce que vous vouliez en général.

L'autre approche en tableur, une colonne auxiliaire avec COUNTIF, est plus lente mais non destructive, et elle vous montre les doublons au lieu de les retirer. Sur un gros fichier, c'est aussi ce qui fera planter Excel, car COUNTIF sur un demi-million de lignes est quadratique.

Sur un téléphone

Sur un téléphone, la version réaliste n'est pas un passage de dédoublonnage complet. Il s'agit de trier par la colonne suspecte, de faire défiler et de voir les répétitions côte à côte, ce qui est le moyen le plus rapide de savoir si un fichier a un problème de doublons.

Une fois que vous les voyez, filtrer sur une clé et lire les quelques lignes qui la partagent répond à la seule question qui compte : est-ce le même enregistrement, ou deux enregistrements qui partagent un champ par hasard ?

CSV Editor - Smart CSViPhone et iPad

Triez par n'importe quelle colonne comme dans Excel, puis supprimez des lignes avec le filtre actif en toute sécurité : les lignes masquées sont protégées, donc une suppression ne touche jamais les données hors du filtre. L'annulation couvre tout, et c'est ce qui rend raisonnable de le faire sur un téléphone.

Ce que ça fait

Vérifier

Trois chiffres, qui doivent concorder :

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

rows et keys doivent maintenant être égaux. Sinon, le dédoublonnage ne s'est pas appliqué à tous les groupes. Et input − deduped doit être égal au nombre de lignes que vous comptiez supprimer, celui de l'étape deux. S'il en a retiré davantage, la clé était plus large ou plus étroite que prévu, et le fichier des lignes écartées que vous avez conservé sauve maintenant votre après-midi.

Questions

Comment supprimer les lignes en double d'un fichier CSV ?
Pour des lignes strictement identiques, `awk 'NR==1 || !seen[$0]++' input.csv > deduped.csv` garde l'en-tête et l'ordre d'origine. Pour des doublons définis par une colonne clé plutôt que par la ligne entière, regroupez d'abord par cette clé pour voir ce que vous supprimeriez, puis choisissez vous-même la ligne qui survit, en général la plus récente selon l'horodatage, plutôt que de laisser l'outil trancher.
Comment trouver les doublons d'un CSV avant de les supprimer ?
Comptez-les par clé : `SELECT email, count(*) n FROM read_csv('input.csv') GROUP BY email HAVING n > 1`. Si une grande part du fichier ressort, la clé est mauvaise : vous comparez une colonne qui n'a jamais été unique. Sélectionnez ensuite toutes les lignes d'une clé en double et lisez-les côte à côte ; c'est là que vous découvrez que les lignes diffèrent dans une colonne qui compte pour vous.
Quelle ligne en double dois-je garder ?
La plus récente, s'il y a un horodatage. Une fenêtre row_number() partitionnée par la clé et triée par date décroissante garde exactement une ligne par clé. Sans horodatage, la ligne la plus complète est un bon substitut. Quand chaque ligne contient ce qui manque à l'autre, la réponse honnête est de les fusionner colonne par colonne plutôt que d'en écarter une.
Pourquoi « Supprimer les doublons » d'Excel supprime-t-il la mauvaise ligne ?
Parce qu'il garde la première occurrence dans l'ordre actuel de la feuille et ne permet pas d'influer sur laquelle c'est. Triez par horodatage décroissant avant de l'exécuter, pour que « garder la première » signifie « garder la plus récente ».
Comment repérer les doublons qui ne sont pas exactement identiques ?
Normalisez pour la comparaison en gardant les valeurs d'origine : minuscules, suppression des espaces, et retrait des non-chiffres dans les numéros de téléphone avant de regrouper. Ces trois étapes attrapent la plupart des doublons réels. La correspondance floue sur les noms est celle à ne pas automatiser : « Jon Smith » et « John Smith » peuvent être une ou deux personnes, et un seuil adapté à un fichier est mauvais pour le suivant.
Comment vérifier que le dédoublonnage a fonctionné ?
Le nombre de lignes du résultat et son nombre de clés distinctes doivent maintenant être égaux, et le nombre de lignes supprimées doit correspondre à celui que vous avez compté avant de supprimer. Écrivez d'abord les lignes écartées dans un fichier séparé, car un dédoublonnage irréversible est un dédoublonnage que vous voudrez annuler.

uos — Développe CSV Editor et Smart CSV Viewer, et a supprimé assez souvent la mauvaise ligne d'une paire de doublons pour noter les vérifications.