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 (
NonevsNaN) 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
| Objectif | Méthode | Exemple |
|---|---|---|
| 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.stret les comparaisons. - Évitez de mélanger des objets Python autant que possible ; les colonnes
objectsont 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=Falsepour 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=Falselors du filtrage pour traiter les valeurs manquantes comme des non-correspondances. - Les groupes nommés dans
extractcré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=Truepour conserver des colonnes alignées ; privilégiezexplodelorsque 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 typeInt64lorsque l’entrée est de typestring.- 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=Falselorsque 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écessitepyarrow). - 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.