Arnaud Margiela

Tu peux juste vérifier que c'est pareil ?

Il y a des mots qui coûtent cher. En mission, le plus cher de tous, c'est « juste ». Tu peux juste regarder ? C'est juste une vérification. Le mot est minuscule et il cache presque toujours un après-midi entier.

Celui-là est tombé un mardi, en visio, pendant qu'un collègue du client faisait défiler son écran trop vite. Migration d'un vieil outil KYC vers une nouvelle plateforme. Le prestataire jurait que la reprise de données était « iso ». Le responsable conformité, lui, voulait une preuve — pas une parole d'éditeur, une preuve. Deux exports. Le « avant » et le « après ». 41 000 lignes chacun. Tu peux juste vérifier que c'est pareil ?

Comparer deux fichiers à la main, ligne par ligne, c'est une tâche qui n'existe que pour punir quelqu'un. On a inventé le tableur pour ne plus jamais faire ça, et le tableur nous y ramène par la porte de derrière, avec un RECHERCHEV qui se brise à la première colonne mal nommée. À 41 000 lignes, ce n'est même plus une corvée, c'est une faute professionnelle : aucun humain ne relit ça correctement, et celui qui prétend l'avoir fait ment.

Donc non. Pas à la main.

J'ai ouvert Claude Code — l'agent de codage d'Anthropic — dans un coin de l'écran et j'ai tapé à peu près ceci :

J'ai deux exports CSV de la même base clients, pris à deux moments différents (une migration de système). Écris-moi un script Python avec pandas qui : (1) trouve les lignes présentes dans l'un et pas dans l'autre, dans les deux sens ; (2) pour les lignes communes, liste les colonnes dont la valeur a changé. La colonne clé est id_client. Sors un fichier Excel avec un onglet par catégorie. Mets les variables à modifier tout en haut du fichier.

Trente secondes plus tard, j'avais un script propre, commenté, qui tournait. C'est là que beaucoup de gens s'arrêtent et postent une capture sur LinkedIn avec le mot « magie ». C'est là, exactement, que le vrai travail commence.

Premier essai : « 0 différence ». Et là, méfiance.

Le script a tourné et m'a annoncé, tout content : 0 ligne modifiée, 0 ajoutée, 0 supprimée. Tout pareil. Mission accomplie en une minute.

Sauf qu'on ne migre pas 41 000 clients d'un système à un autre sans qu'une seule valeur bouge. Jamais. Un « 0 » parfait, en réconciliation, ce n'est pas une bonne nouvelle : c'est un voyant rouge. Ça veut presque toujours dire que la comparaison n'a rien comparé du tout.

Le coupable, je le connaissais avant même de regarder. Les id_client du vieux système ressemblaient à 0042817. pandas, par défaut, lit ça comme un nombre, balance les zéros de tête, et le transforme en 42817. Le nouveau système, lui, exportait l'ID entre guillemets, propre, avec ses zéros. Résultat : aucune clé d'un fichier ne correspondait à aucune clé de l'autre. Le script ne voyait pas « tout pareil », il voyait deux populations de clients totalement étrangères l'une à l'autre — et il en concluait, faute de mieux, que rien ne « correspondait » donc rien n'avait « changé ».

Claude Code écrit du bon code. Mais c'est un intérimaire qui ne connaît pas la maison : il ne sait pas que, chez ce client, les identifiants ont des zéros sacrés, que le vieux serveur crache du Windows-1252 et pas de l'UTF-8, et qu'une partie des exports traîne des doublons hérités d'une fusion ratée en 2019. Ces trois détails ne sont écrits nulle part dans le prompt. Ils sont dans ma tête, parce que c'est mon métier. Le code ne remplace pas ça. Il l'attend.

J'ai donc remis trois fois l'ouvrage sur le métier :

  1. Forcer la lecture en texte (dtype=str) pour que 0042817 reste 0042817. La comparaison s'est mise à trouver des correspondances.
  2. Changer l'encodage en cp1252, parce que les é du vieux système arrivaient en é et qu'un « Müller » cassé n'est pas égal à un « Müller » propre — donc faux positif garanti.
  3. Ajouter un garde-fou sur l'unicité de la clé, parce que dès que id_client est en double, toute la logique de comparaison part en vrille sans prévenir.

Et avant de livrer quoi que ce soit, j'ai pris dix lignes au hasard et je les ai vérifiées à la main, à l'œil, dans les deux fichiers. Dix sur 41 000. C'est ridicule, et c'est non négociable. Tant que je n'ai pas vu le code donner la bonne réponse sur un cas que je connais déjà, je ne lui fais pas confiance sur les 40 990 autres.

Le code (celui qui marche, après les trois claques)

# --- VOS VARIABLES À MODIFIER ---
FICHIER_A = "export_ancien_systeme.csv"   # la "vérité d'avant"
FICHIER_B = "export_nouveau_systeme.csv"  # la "vérité d'après"
CLE = "id_client"                          # la colonne qui identifie une ligne de façon unique
COLONNES_A_COMPARER = ["nom", "pays_residence", "statut_risque", "date_revue"]
ENCODAGE = "cp1252"                        # essayer "utf-8" ou "latin-1" si les accents sont cassés
SORTIE = "rapport_comparaison.xlsx"
# ---------------------------------

import pandas as pd

# Lecture en TEXTE (dtype=str) pour ne pas perdre les zéros de tête (0042817 -> 42817)
a = pd.read_csv(FICHIER_A, dtype=str, encoding=ENCODAGE).fillna("")
b = pd.read_csv(FICHIER_B, dtype=str, encoding=ENCODAGE).fillna("")

# Nettoyage minimal : espaces parasites en début/fin de clé
a[CLE] = a[CLE].str.strip()
b[CLE] = b[CLE].str.strip()

# Garde-fou : la clé est-elle vraiment unique ? Sinon, la comparaison sera fausse.
for nom, df in [("A", a), ("B", b)]:
    doublons = df[CLE].duplicated().sum()
    if doublons:
        print(f"ATTENTION : {doublons} cles en double dans le fichier {nom}. A nettoyer avant de continuer.")

cles_a, cles_b = set(a[CLE]), set(b[CLE])

# Lignes disparues / apparues
supprimees = a[a[CLE].isin(cles_a - cles_b)]
ajoutees   = b[b[CLE].isin(cles_b - cles_a)]

# Lignes presentes des deux cotes : qu'est-ce qui a change, colonne par colonne ?
a_idx = a.set_index(CLE)
b_idx = b.set_index(CLE)
modifs = []
for cle in sorted(cles_a & cles_b):
    for col in COLONNES_A_COMPARER:
        avant, apres = a_idx.at[cle, col], b_idx.at[cle, col]
        if avant != apres:
            modifs.append({"id_client": cle, "colonne": col, "avant": avant, "apres": apres})
modifs = pd.DataFrame(modifs)

# Un rapport Excel, un onglet par categorie
with pd.ExcelWriter(SORTIE) as writer:
    supprimees.to_excel(writer, sheet_name="Disparues", index=False)
    ajoutees.to_excel(writer, sheet_name="Apparues", index=False)
    modifs.to_excel(writer, sheet_name="Modifiees", index=False)

print(f"{len(supprimees)} disparues, {len(ajoutees)} apparues, {len(modifs)} valeurs modifiees.")
print(f"Rapport ecrit dans {SORTIE}")

Les trois lignes qui font tout le travail invisible : dtype=str (les zéros), encoding="cp1252" (les accents), et le test de doublons. Le reste, n'importe quel agent vous l'écrit. Ces trois-là, il faut les exiger — et pour les exiger, il faut savoir qu'elles existent.

Le guide pour les non-codeurs

Vous n'avez rien installé, vous ne voulez rien installer, et vous avez raison. On va tout faire dans le navigateur, gratuitement, avec Google Colab.

  1. Allez sur colab.research.google.com et cliquez sur « Nouveau notebook ».
  2. À gauche, cliquez sur l'icône dossier (« Fichiers »), puis glissez-y vos deux exports CSV.
  3. Copiez le bloc de code ci-dessus dans la première cellule.
  4. Modifiez uniquement le bloc VOS VARIABLES À MODIFIER : les deux noms de fichiers, le nom de votre colonne clé, et la liste des colonnes à comparer.
  5. Appuyez sur Maj + Entrée pour exécuter. En bas, vous lisez le compte : disparues, apparues, modifiées.
  6. Toujours dans le panneau « Fichiers », faites un clic droit sur rapport_comparaison.xlsx → Télécharger. Voilà votre preuve, en trois onglets.

Si les accents sont cassés dans le rapport, remplacez cp1252 par utf-8 et relancez. Si vous voyez un avertissement « clés en double », arrêtez tout : votre fichier source a un problème que le script ne corrigera pas à votre place.

Ce que l'agent m'a fait gagner, ce n'est pas l'analyse. L'analyse — savoir que les zéros comptent, qu'un « 0 différence » est suspect, qu'il faut vérifier dix lignes à la main — c'est précisément ce pour quoi le client me paie, et ça, ça reste entièrement dans ma tête. Ce qu'il m'a fait gagner, c'est la frappe. Les quarante minutes de pandas que je connais mais que je tape lentement, en cherchant deux fois sur quel onglet écrit to_excel. Il a écrit, j'ai pensé. C'est le bon partage.

Le rapport faisait trois onglets et 217 valeurs modifiées que personne, côté prestataire, n'avait vues. Le responsable conformité a dit « ah ». J'ai rangé le portable dans la sacoche.

⬅ Article précédent
En vrac — 22 mai 2026 : le faux fichier au vrai format et un patron de couture

Article suivant ➡
Lundi 25 mai 2026