Skip to content

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

Mis à jour le

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.