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 (
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.