Skip to content

Opérations sur les chaînes Pandas : Nettoyage de texte vectorisé

Updated on

Les colonnes de texte alimentent la recherche, la segmentation et la création de features, mais de nombreux pipelines parcourent encore les lignes en boucle ou mélangent None/NaN, ce qui conduit à des filtres cassés et à du code lent.

  • Problème : La casse, les espaces et les correspondances partielles désordonnés rendent les jointures et l’analyse peu fiables.
  • Agitation : Les boucles Python ligne par ligne sont lentes, et les valeurs manquantes incohérentes (None vs NaN) cassent les comparaisons.
  • Solution : Utiliser le type de données string de pandas avec les méthodes vectorisées .str, un contrôle explicite des regex, et des découpages/explosions sûrs pour garder le traitement de texte rapide et prévisible.

Want an AI agent that understands your pandas text cleaning and notebook context?

RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.

👉 Try RunCell: runcell.dev (opens in a new tab)


Référence rapide

ObjectifMéthodeExemple
Normaliser casse / espaces.str.casefold(), .str.strip()s.str.strip().str.casefold()
Remplacement littéral (rapide).str.replace(..., regex=False)s.str.replace("-", " ", regex=False)
Extraction / recherche regex.str.extract(), .str.contains()s.str.extract(r"(\d{4})")
Découper en colonnes.str.split(expand=True)s.str.split("/", expand=True, n=2)
Découper en lignes.str.split().explode()df.assign(tag=df["tags"].str.split(",")).explode("tag")
Longueur / comptages.str.len(), .str.count()s.str.count(r"\d")

Commencer avec un vrai type string

import pandas as pd
 
df["title"] = df["title"].astype("string[python]")
  • L’utilisation du type string (ou "string[pyarrow]" quand Arrow est installé) conserve les valeurs manquantes en tant que <NA>, ce qui fonctionne bien avec les méthodes .str et les comparaisons.
  • Évitez de mélanger des objets Python autant que possible ; les colonnes object sont plus lentes et moins cohérentes pour les opérations textuelles.

Modèles de nettoyage de base

df["clean_name"] = (
    df["name"]
      .str.strip()
      .str.replace(r"\s+", " ", regex=True)
      .str.title()
)
  • Utilisez regex=False pour les remplacements littéraux simples afin d’éviter une interprétation regex accidentelle et d’améliorer les performances.
  • .str.normalize("NFKC") aide à unifier les variantes Unicode lors de la mise en correspondance des entrées utilisateur.

Suppression du bruit et gestion de la casse

df["search_key"] = df["product"].str.casefold().str.replace("-", " ", regex=False)

casefold est plus robuste que lower pour les comparaisons de texte internationalisées.


Filtrer et extraire

# Vérifications exactes de préfixe/suffixe
promo_rows = df[df["code"].str.startswith("PROMO", na=False)]
 
# Recherche regex avec gestion sûre de NA
has_year = df["description"].str.contains(r"\b20\d{2}\b", regex=True, na=False)
 
# Groupes capturés vers des colonnes
df[["year", "country"]] = df["id"].str.extract(r"(?P<year>\d{4})-(?P<country>[A-Z]{2})")
  • Définissez na=False lors du filtrage pour traiter les valeurs manquantes comme des non-correspondances.
  • Les groupes nommés dans extract créent des colonnes lisibles sans étape de renommage supplémentaire.

Split, expand et explode

# Découper en plusieurs colonnes
df[["city", "state"]] = df["location"].str.split(",", n=1, expand=True)
 
# Transformer une colonne de type liste en lignes
tags = df.assign(tag=df["tags"].str.split("|"))
tags = tags.explode("tag").assign(tag=lambda t: t["tag"].str.strip())
  • Utilisez expand=True pour conserver des colonnes alignées ; privilégiez explode lorsque chaque cellule contient plusieurs tokens qui doivent devenir des lignes.
  • Nettoyez les morceaux (str.strip, str.casefold) avant les jointures ou les agrégations.

Compter et mesurer le texte

df["word_count"] = df["abstract"].str.split().str.len()
df["digit_count"] = df["code"].str.count(r"\d")
  • .str.len() respecte <NA> ; les résultats sont de type Int64 lorsque l’entrée est de type string.
  • Combinez avec fillna(0) si vous avez besoin d’entiers classiques pour les pipelines numériques en aval.

Conseils de performances et de sécurité

  • Préférez les méthodes vectorisées .str à apply(lambda ...) ; elles sont plus rapides et gèrent nativement les valeurs manquantes.
  • Spécifiez regex=False lorsque vous ne faites que des remplacements littéraux pour éviter le surcoût des regex.
  • Pour les grandes colonnes de texte, envisagez string[pyarrow] pour réduire la mémoire utilisée et accélérer les opérations courantes (nécessite pyarrow).
  • Normalisez les clés intermédiaires une seule fois (strip + casefold) et réutilisez-les pour les jointures ou la déduplication au lieu de les recalculer.

Les opérations vectorisées sur les chaînes gardent le nettoyage de texte concis et performant. Combinez-les avec pandas-data-cleaning pour des contrôles de qualité plus larges et associez-les à pandas-merge-join lorsque les clés normalisées sont prêtes pour des jointures fiables.