- Apprendre
- Informatique et numérique
- Science des données et IA
- Python et pandas : NumPy, analyse et visualisation de données
- Préparer les données avec pandas
Préparer les données avec pandas
IntermédiaireUnité 4 sur 8 de la formation Formation : Python et pandas : NumPy, analyse et visualisation de données
Ce que tu vas apprendre
- Détecter les valeurs manquantes et les lignes en double dans un DataFrame pandas, décider de les supprimer, de les remplacer ou de les conserver, et vérifier l’effet de chaque choix sur les données.
- Détecter les valeurs manquantes dans un DataFrameReconnaître les marqueurs de données manquantes de pandas, compter ces données par colonne et par ligne, et repérer les codes cachés qui représentent des valeurs manquantes.
- Supprimer ou remplacer les valeurs manquantesSupprimer les lignes ou colonnes incomplètes avec dropna, ou remplacer les valeurs manquantes par des valeurs fixes, des statistiques, des valeurs voisines ou une interpolation, et choisir la méthode adaptée aux données.
- Repérer et supprimer les lignes en doubleMarquer et supprimer les lignes répétées avec duplicated et drop_duplicates, comparer uniquement les colonnes clés si nécessaire et conserver la bonne copie de chaque enregistrement.
- Détecter les valeurs manquantes dans un DataFrame
- Modifier les valeurs d’une colonne de façon maîtrisée : remplacer des codes, mettre des valeurs en correspondance, convertir des types, renommer des étiquettes et transformer des nombres en groupes, en valeurs mises à l’échelle et en colonnes indicatrices.
- Remplacer, mettre en correspondance et convertir des valeursRemplacer des valeurs exactes avec replace, mettre des valeurs en correspondance à l’aide d’un dictionnaire ou d’une fonction avec map, renommer des lignes et des colonnes, et convertir du texte en nombres de façon sûre.
- Discrétiser, mettre à l’échelle, écrêter et encoder des valeursRegrouper des nombres dans des intervalles avec cut et qcut, mettre des colonnes à l’échelle, limiter les valeurs extrêmes avec clip et créer des colonnes indicatrices pour les catégories.
- Remplacer, mettre en correspondance et convertir des valeurs
- Standardiser les colonnes textuelles et y effectuer des recherches avec l’accesseur str et les expressions régulières, puis stocker efficacement sous forme catégorielle les colonnes dont l’ensemble de valeurs est fixe.
- Nettoyer les colonnes textuelles avec les méthodes de chaînes de caractèresUtiliser les méthodes str vectorisées pour supprimer les espaces superflus, modifier la casse, découper, rechercher, remplacer et combiner le texte de toutes les lignes d’une colonne à la fois.
- Rechercher et extraire des motifs à l’aide d’expressions régulièresÉcrire des expressions régulières simples et les utiliser avec contains, extract, findall et replace pour tester, extraire et nettoyer des parties structurées de texte.
- Utiliser le type catégorielConvertir les colonnes qui comportent un ensemble limité de valeurs en colonnes catégorielles, utiliser leurs catégories et leurs codes, et employer des catégories ordonnées pour les valeurs qui ont un ordre naturel.
- Nettoyer les colonnes textuelles avec les méthodes de chaînes de caractères
- Réunir les données de plusieurs tables : faire correspondre les lignes par colonnes clés ou étiquettes d’index avec merge et join, compléter les valeurs manquantes depuis une deuxième source et empiler des tables avec concat.
- Fusionner des DataFrame sur des colonnes clésCombiner deux tables en faisant correspondre les valeurs de colonnes clés avec merge, choisir le type de jointure et vérifier les lignes sans correspondance ou multipliées dans le résultat.
- Effectuer une jointure sur l’index et compléter les valeurs manquantes à partir d’une autre tableFusionner sur les étiquettes d’index avec join ou left_index et right_index, et utiliser combine_first et l’alignement des étiquettes pour compléter les valeurs manquantes depuis une deuxième source.
- Empiler des DataFrame avec concatAssembler des tables selon les lignes ou les colonnes avec pd.concat, maîtriser l’index et les colonnes du résultat et indiquer la provenance de chaque partie.
- Fusionner des DataFrame sur des colonnes clés
- Travailler avec des tables qui possèdent plusieurs niveaux d’index et passer du format long au format large et inversement avec stack, unstack, pivot et melt.
- Travailler avec des index hiérarchiquesConstruire et lire un MultiIndex, sélectionner des données selon les niveaux externes et internes, réordonner et trier les niveaux, et déplacer des niveaux entre l’index et les colonnes.
- Remodeler les données avec stack et unstackDéplacer les étiquettes de colonnes dans l’index avec stack et les niveaux d’index dans les colonnes avec unstack, et traiter les combinaisons manquantes que le remodelage fait apparaître.
- Passer du format long au format large et inversement avec pivot et meltReconnaître les formats long et large, transformer des données au format long en table au format large avec pivot ou pivot_table, et transformer une table au format large en données au format long avec melt.
- Travailler avec des index hiérarchiques
Préparer les données avec pandas : cours
1Repérer et traiter les valeurs manquantes et les doublons
Une valeur manquante, un zéro et un enregistrement répété ont des significations différentes. Apprends à quantifier les données manquantes avant de choisir ce que tu conserves, supprimes ou estimes, et à identifier les doublons à l’aide des colonnes qui définissent un enregistrement. De petites tables météorologiques et de commandes montrent comment pandas met ces décisions en œuvre et comment elles influent sur le nombre de lignes, les types de données et les statistiques. Chaque modification produit un résultat visible que tu peux vérifier avant de poursuivre une analyse.
1.1 Repérer les valeurs manquantes avant de calculer
Une donnée manquante est une valeur inconnue ou indisponible. pandas stocke un marqueur spécial à sa place. Détecte ce marqueur avant de calculer des totaux ou de décider quelles lignes sont utilisables.
Reconnaître les marqueurs
Le marqueur dépend du type de données. Les colonnes de nombres à virgule flottante utilisent NaN, les colonnes de dates et heures utilisent NaT, et les types nullables comme "Int64", "boolean" et "string" utilisent pd.NA. pandas 3 infère le type str pour les colonnes textuelles, avec NaN pour le texte manquant. Le None de Python est lui aussi reconnu comme manquant. Utilise import pandas as pd et import numpy as np pour les exemples.
df.isna() produit un tableau booléen ayant les mêmes lignes et colonnes que df. Un True marque une valeur manquante ; df.notna() marque les valeurs présentes. Les alias isnull() et notnull() remplissent les mêmes fonctions. Ne compare pas une colonne à np.nan : NaN est différent même de lui-même, donc s == np.nan ne repère pas les valeurs manquantes.
Compter les cellules et les lignes concernées
Considère ces relevés météorologiques :
| city | temp_c | rain_mm |
|---|---|---|
| Lima | 18,0 | 0,0 |
| Oslo | NaN | 4,0 |
| Pune | 31,0 | NaN |
| Kyiv | NaN | NaN |
Un True booléen compte pour 1, donc df.isna().sum() donne 0 ville, 2 températures et 2 relevés de pluie manquants. df.isna().mean() donne les proportions 0.0, 0.5 et 0.5. La proportion de chaque colonne utilise les quatre lignes comme dénominateur.
Pour trouver les lignes concernées, utilise df.isna().any(axis=1). Le résultat est False, True, True, True ; sa somme vaut 3. En revanche, df.isna().sum().sum() donne 4 cellules manquantes. Kyiv compte pour deux cellules mais une seule ligne concernée. Utilise la mesure qui répond à ta question.
Reconnaître les codes cachés de valeurs manquantes
Un instrument peut enregistrer un relevé indisponible sous la forme -999, "-" ou "unknown". Ce sont des valeurs ordinaires tant que tu ne les convertis pas. Après avoir confirmé la signification du code, utilise df.replace([-999, "unknown"], np.nan). Lors du chargement d’un CSV, na_values=[-999, "unknown"] ajoute ces codes aux marqueurs reconnus. Les champs CSV vides et les chaînes courantes comme "NA", "n/a" et "NULL" sont déjà reconnus par défaut.
Un relevé de pluie égal à zéro peut signifier qu’il n’a pas plu ; remplacer tous les zéros détruirait donc des observations réelles. De plus, une chaîne vide créée en mémoire, "", et une chaîne contenant des espaces ne sont pas considérées comme manquantes par isna(). Examine le texte stocké ainsi que les décomptes de marqueurs. Pour inclure les catégories manquantes dans un tableau des effectifs et des fréquences, utilise value_counts(dropna=False).
Vérifier les calculs et les types de données
Pour s = pd.Series([4, np.nan, 8]), s.mean() vaut 6.0 : la méthode utilise les deux valeurs connues. s.count() vaut 2, tandis que len(s) vaut 3. Diviser s.sum() par len(s) donne 4.0 et traite à tort la valeur manquante comme un zéro. La plupart des statistiques ignorent les valeurs manquantes par défaut ; une colonne entièrement manquante a une somme de 0 mais une moyenne de NaN.
Une valeur manquante peut aussi modifier le stockage. pd.Series([3, None, 5]) devient float64 et contient 3.0, NaN et 5.0. Indiquer dtype="Int64" conserve des valeurs entières avec <NA> pour la valeur manquante. Le I majuscule identifie le type entier nullable de pandas.
Points clés
- Utilise
isna()pour détecter les marqueurs de valeurs manquantes dans les différents types de données. - Compte séparément les cellules manquantes et les lignes comportant au moins une valeur manquante.
- Convertis les codes dont la signification manquante est confirmée ; conserve les zéros valides.
- Vérifie le nombre de valeurs connues utilisées dans une statistique.
- Utilise
"Int64"lorsque des valeurs entières nécessitent un marqueur de valeur manquante.
1.2 Choisir les valeurs à supprimer ou à remplacer
Supprimer une ligne retire ses valeurs connues en même temps que ses valeurs manquantes. Remplacer une valeur manquante conserve la ligne mais introduit une estimation. Choisis selon la signification de l’observation et les colonnes nécessaires à l’analyse.
Maîtriser les lignes supprimées
df.dropna() supprime toutes les lignes qui comportent une valeur manquante. Dans la table météorologique, seule Lima reste. Limite la décision avec subset, ou exige un nombre minimal de cellules présentes avec thresh.
| Appel | Lignes conservées | Raison |
|---|---|---|
df.dropna(subset=["temp_c"]) | Lima, Pune | La température est présente |
df.dropna(thresh=2) | Lima, Oslo, Pune | Au moins deux cellules sont présentes |
df.dropna(how="all") | Les quatre | Chaque ligne contient une ville |
axis="columns" supprime les colonnes qui comportent des valeurs manquantes et ne conserve ici que city. Dans une table comportant de nombreuses colonnes, la règle par défaut appliquée aux lignes peut supprimer une grande partie des données, car une valeur manquante dans n’importe quelle colonne suffit. Compare len(df) avant et après la suppression.
Affecter le résultat
Apprends la forme avec réaffectation : df = df.dropna(). Par défaut, les méthodes de nettoyage renvoient un nouvel objet. pandas 3.1 déprécie inplace=True pour des méthodes comme dropna, drop_duplicates et rename.
Pour une colonne, écris df["temp_c"] = df["temp_c"].fillna(0). Avec la copie à l’écriture de pandas 3, un appel chaîné comme df["temp_c"].fillna(0, inplace=True) ne modifie jamais le DataFrame parent. L’affectation indique explicitement la destination.
Remplacer par une valeur compatible
Un dictionnaire par colonne permet de fournir des valeurs adaptées à une table mixte : df.fillna({"rain_mm": 0, "city": "Unknown"}). Les colonnes absentes du dictionnaire conservent leurs valeurs manquantes. Un scalaire comme 0 est pratique pour une table composée uniquement de nombres dont toutes les colonnes l’acceptent. Remplacer du texte manquant par un nombre est incompatible ; pandas 3.1 émet un avertissement et une future version le refusera.
Les températures connues sont 18,0 et 31,0. Leur moyenne est de 24,5, donc df["temp_c"].fillna(df["temp_c"].mean()) place 24,5 dans les deux cases manquantes. Une valeur extrême peut fortement tirer la moyenne ; la médiane y est moins sensible. Avant le remplacement, conserve un indicateur avec df["temp_missing"] = df["temp_c"].isna() afin de pouvoir distinguer les valeurs estimées des valeurs observées.
Le remplacement par la moyenne réduit la dispersion apparente de la colonne. Une valeur fixe éloignée peut l’augmenter. Remplacer une mesure de pluie manquante par 0 affirme qu’il n’a pas plu, ce qui ne convient pas si le capteur était éteint.
Utiliser les relevés voisins lorsque l’ordre compte
ffill() propage la dernière valeur connue vers l’avant ; bfill() propage la prochaine valeur connue vers l’arrière. Pour 12,0 ; NaN ; NaN ; NaN ; 15,0, la propagation vers l’avant donne quatre valeurs 12.0 suivies de 15.0. ffill(limit=1) ne remplace que la première valeur manquante de cette suite. Une valeur manquante en début de série n’a pas de valeur précédente et reste manquante. Utilise directement ffill() ; fillna(method="ffill") a été supprimé dans pandas 3.
interpolate() estime les valeurs entre des positions voisines. Pour 10, NaN, NaN, 16, l’interpolation linéaire donne 10, 12, 14, 16. Elle convient aux mesures qui évoluent progressivement dans un ordre qui a un sens. Propager ou interpoler des valeurs entre des villes sans lien imposerait une relation que les lignes n’ont pas.
Après toute opération, exécute à nouveau isna().sum() et vérifie le nombre de lignes. Un appel de méthode réussi indique que le code s’est exécuté ; ces vérifications indiquent ce qui a changé.
Points clés
- Utilise
subset,howouthreshpour indiquer quelles valeurs manquantes comptent. - Affecte les résultats renvoyés au DataFrame ou à la colonne que tu souhaites modifier.
- Choisis des valeurs de remplacement adaptées au type de la colonne et à la signification de la valeur manquante.
- Conserve un indicateur des valeurs manquantes avant de les remplacer par des estimations.
- N’utilise les méthodes fondées sur les valeurs voisines que lorsque l’ordre des lignes a un sens.
- Vérifie le nombre de lignes et de valeurs manquantes après le nettoyage.
1.3 Identifier l’enregistrement avant de supprimer ses copies
Deux lignes peuvent se ressembler sans décrire le même événement. Avant de supprimer des doublons, détermine quelles valeurs identifient un enregistrement. Un identifiant de commande peut identifier une commande ; le client et la date seuls peuvent désigner plusieurs achats légitimes.
Marquer les copies supplémentaires
df.duplicated() renvoie un booléen par ligne. Par défaut, cette méthode compare toutes les colonnes, conserve la première occurrence et marque les copies suivantes par True. La somme du résultat compte les copies supplémentaires, et non tous les membres des groupes répétés.
Considère six lignes de commandes d’identifiants 101, 102, 102, 103, 104, 104. Les deux lignes 102 sont identiques. Les deux lignes 104 ont des poids enregistrés différents, 0,5 kg et 0,8 kg. Lorsque toutes les colonnes sont comparées, il y a une copie supplémentaire : df.duplicated().sum() vaut 1. df.drop_duplicates() conserve cinq lignes car les deux lignes 104 différentes ne sont pas des copies exactes.
Comparer les colonnes qui définissent l’identité
df.duplicated(subset=["order_id"]) ne compare que les identifiants. Cette méthode marque le deuxième 102 et le deuxième 104, soit deux copies supplémentaires. Les valeurs des autres colonnes n’influent plus sur cette décision. Examine les poids contradictoires avant de choisir l’enregistrement de commande à conserver.
Valeur de keep | Traitement d’un groupe répété |
|---|---|
"first" | Conserver la première ligne dans l’ordre actuel |
"last" | Conserver la dernière ligne dans l’ordre actuel |
False | Supprimer tous les membres d’un groupe répété |
df.drop_duplicates(subset="order_id", keep="last") conserve la version de 0,8 kg de la commande 104 dans cet ordre. Conserver la dernière ligne ne signifie pas en soi conserver l’enregistrement le plus récent. Établis d’abord cet ordre :
latest = df.sort_values("updated").drop_duplicates(
subset="customer_id", keep="last"
)
Le tri selon updated place les enregistrements anciens avant les plus récents. La recherche de doublons ne compare ensuite que customer_id : des dates de mise à jour différentes n’empêchent donc pas de reconnaître deux lignes comme des versions du même client.
Distinguer les valeurs des lignes des étiquettes d’index
Ces méthodes comparent les valeurs et ignorent les étiquettes d’index. Des lignes identiques portant les étiquettes 4 et 9 comptent tout de même comme des doublons. Pour cette vérification, les valeurs manquantes aux positions correspondantes sont considérées comme égales. Pour rechercher les étiquettes elles-mêmes répétées, utilise df.index.duplicated().
La comparaison exacte tient aussi compte des différences de casse et d’espacement. Les valeurs « Lisbon » précédée d’un espace, « lisbon » et « LISBON » suivie d’un espace sont distinctes. Nettoie-les avec .str.strip().str.lower() avant de rechercher les doublons lorsque ces écritures désignent la même ville. Sinon, nunique() comptera trois noms pour un seul lieu.
Vérifier l’unicité là où la relation l’exige
Une table de correspondance doit comporter une ligne par clé de correspondance lorsque chaque enregistrement doit recevoir un seul ensemble de détails. lookup["customer_id"].is_unique vérifie cette exigence. Des identifiants de clients répétés dans une table de commandes sont normaux, car un client peut passer plusieurs commandes.
Si une clé de correspondance se répète, une fusion ultérieure répète chaque commande correspondante pour chaque ligne correspondante de la table de correspondance. Supprimer les doublons des commandes éliminerait de véritables achats sans corriger la table de correspondance. Vérifie la clé prévue dans la bonne table, examine les enregistrements contradictoires et compare le nombre de lignes après la suppression.
Points clés
- Définis un enregistrement à l’aide des bonnes colonnes clés avant de supprimer ses copies.
duplicated().sum()compte les copies suivantes avec l’option par défautkeep="first".- Trie par date de mise à jour avant de conserver l’enregistrement le plus récent.
- La recherche de doublons parmi les valeurs des lignes et celle d’étiquettes d’index répétées sont deux vérifications distinctes.
- L’unicité des clés de correspondance évite la multiplication accidentelle des lignes lors des fusions.
2Transformer les valeurs par remplacement, mise en correspondance et discrétisation
Transformer une colonne modifie la signification ou la représentation de ses valeurs. Choisis entre les remplacements exacts, les mises en correspondance, la conversion numérique, les intervalles, les valeurs mises à l’échelle et les colonnes indicatrices. Tu examineras les entrées et les sorties de chaque méthode, y compris le sort des valeurs sans correspondance et des valeurs situées aux bornes, afin qu’une opération pratique ne modifie pas silencieusement les catégories ou ne fasse pas perdre des mesures utilisables.
2.1 Modifier les valeurs et les étiquettes de façon réfléchie
Un remplacement modifie les valeurs correspondantes, une mise en correspondance traduit les valeurs et un renommage modifie les étiquettes. Ces opérations peuvent se ressembler dans le code, mais produisent des résultats différents lorsqu’une valeur est absente d’un dictionnaire.
Remplacer des valeurs exactes
s.replace("N/A", np.nan) ne modifie que les cellules égales à "N/A". Une liste peut indiquer plusieurs anciennes valeurs : s.replace(["-", "?"], np.nan). Un dictionnaire fournit des remplacements distincts, comme dans s.replace({"M": "male", "F": "female"}). Les valeurs sans correspondance restent inchangées.
Pour une table entière, un dictionnaire imbriqué limite la modification à une colonne : df.replace({"status": {0: "open", 1: "closed"}}). Cela évite de modifier d’autres zéros et uns sans rapport ailleurs dans la table. Affecte le résultat renvoyé pour conserver la modification.
replace recherche des cellules entières. Avec « Main St » et « St », s.replace("St", "Street") ne modifie que « St ». Pour modifier des parties d’une chaîne, utilise s.str.replace("St", "Street", regex=False), qui produit aussi « Main Street ».
Mettre en correspondance à l’aide d’un dictionnaire
Pour les codes « PT », « JP » et « KE », compare le même dictionnaire dans deux méthodes :
| Méthode | PT | JP | KE |
|---|---|---|---|
s.map({"PT": "Portugal", "JP": "Japan"}) | Portugal | Japan | NaN |
s.replace({"PT": "Portugal", "JP": "Japan"}) | Portugal | Japan | KE |
Un dictionnaire transmis à map définit les sorties disponibles. Une clé absente n’a pas de sortie et devient une valeur manquante. Vérifie ensuite isna().sum() pour repérer une correspondance incomplète.
map accepte aussi une fonction : s.map(lambda x: x * 1000) convertit des valeurs en kilomètres en mètres. Pour ce calcul, s * 1000 est plus simple et plus rapide car l’opération porte sur toute la colonne. DataFrame.map applique une fonction cellule par cellule ; cette méthode remplace applymap, qui a été supprimée.
Convertir du texte en nombres
astype demande un type de données, comme "float64", "Int64" ou "category". Cette méthode déclenche une erreur si une valeur ne peut pas être convertie. Pour les textes "12", "7.5" et "n/a", pd.to_numeric(s, errors="coerce") produit en revanche 12.0, 7.5 et NaN. La coercition conserve les nombres lisibles mais impose d’examiner les échecs.
Le formatage peut empêcher la conversion même lorsque le nombre est valide. Pour « 1,200 » et « 950 », supprime d’abord le séparateur de milliers :
cleaned = s.str.replace(",", "", regex=False)
numbers = pd.to_numeric(cleaned, errors="coerce")
failed = s.notna() & numbers.isna()
Ici, failed marque les valeurs qui étaient présentes avant la conversion mais sont devenues manquantes. Comparer uniquement les nombres de valeurs manquantes donne un total utile ; le masque permet aussi de retrouver le texte d’origine à examiner. Supprime de la même manière et de façon réfléchie les unités connues des mesures textuelles avant la conversion.
Renommer les étiquettes
df.rename(columns={"Qty": "quantity"}) modifie un en-tête de colonne sans changer ses cellules. df.rename(columns=str.lower) met tous les en-têtes en minuscules. Une séquence comme df.columns.str.strip().str.lower().str.replace(" ", "_", regex=False) transforme « Total KG » suivi d’un espace en total_kg ; affecte-la à df.columns.
Utilise replace ou map pour les valeurs à l’intérieur d’une colonne. Utilise rename pour les étiquettes qui servent à sélectionner ces valeurs.
Points clés
replaceconserve les valeurs sans correspondance ;mapavec un dictionnaire les rend manquantes.- Utilise
.str.replacepour modifier une partie de chaque valeur textuelle. - Privilégie les calculs vectorisés pour les calculs simples sur les colonnes.
- Examine les nouvelles valeurs manquantes après une coercition numérique.
renamemodifie les étiquettes et laisse les valeurs des données inchangées.
2.2 Regrouper et mettre à l’échelle les mesures
Certaines analyses nécessitent des mesures exactes, d’autres des groupes ou des plages numériques comparables. Garde leur signification claire : la discrétisation crée des catégories, la mise à l’échelle modifie l’échelle numérique et l’écrêtage remplace les valeurs extrêmes.
Répartir les valeurs dans des intervalles
pd.cut(ages, [18, 30, 45, 65]) utilise les intervalles (18, 30], (30, 45] et (45, 65]. La parenthèse exclut la borne gauche ; le crochet fermant inclut la borne droite. Les âges 19, 25 et 30 entrent dans le premier intervalle, 41 dans le deuxième et 64 dans le troisième. L’âge 18 devient manquant car il se trouve sur la borne gauche exclue.
include_lowest=True inclut cette valeur minimale dans le premier intervalle. right=False crée au contraire des intervalles fermés à gauche comme [18, 30), si bien que 30 entre dans le deuxième intervalle. Les valeurs situées hors de tous les intervalles restent manquantes. Teste les bornes exactes ainsi que des valeurs typiques situées entre elles.
Il faut une étiquette par intervalle, soit une de moins que le nombre de bornes. Avec labels=["18-30", "31-45", "46-65"] et include_lowest=True, les six âges ci-dessus donnent les effectifs 4, 1 et 1. Ces étiquettes décrivent des âges entiers ; les bornes des intervalles continuent de déterminer l’affectation.
Choisir les bornes ou les effectifs des groupes
| Opération | Ce qu’elle détermine | Utilité |
|---|---|---|
pd.cut(x, [18, 30, 45, 65]) | Bornes fixes | Intervalles qui ont un sens |
pd.cut(x, 4) | Quatre intervalles de même amplitude | Comparer des plages de valeurs |
pd.qcut(x, 4) | Quatre groupes d’effectifs à peu près égaux | Comparer les rangs dans les données |
Pour 2, 4, 6, 8, 10, 12, 14, 16, qcut donne deux valeurs par groupe défini par les quartiles. Des groupes de même effectif ne couvrent pas nécessairement des intervalles de même amplitude.
Mettre à l’échelle sans créer de groupes
La normalisation min-max utilise (x - x.min()) / (x.max() - x.min()). Pour 10, 20, 40, l’étendue est de 30 : les résultats sont 0, environ 0,333 et 1. Le minimum et le maximum sont tous deux nécessaires ; diviser par le seul maximum est une opération différente. Une colonne constante a une étendue nulle, donc cette expression ne peut pas lui donner une dispersion mise à l’échelle utile.
Le centrage et la réduction utilisent (x - x.mean()) / x.std(). Pour 10, 20, 30, la moyenne est de 20 et l’écart-type d’échantillon utilisé par défaut par pandas est de 10. Soustraire 20 et diviser par 10 donne les scores z -1, 0 et 1. Un score z décrit la distance à la moyenne en unités d’écart-type, pas une étiquette d’intervalle.
Écrêter et encoder
pd.Series([5, 12, 250, 8]).clip(upper=100) donne 5, 12, 100, 8. Contrairement à un filtre, clip conserve la ligne et remplace le nombre extrême. Examine les grandes valeurs avec describe() ou un filtre avant de les écrêter : une grande mesure réelle reste une donnée.
pd.get_dummies(s) crée une colonne indicatrice booléenne par catégorie. Avec rouge, vert, rouge, bleu, chaque ligne vaut True uniquement dans la colonne de sa couleur. Utilise dtype=int pour obtenir des zéros et des uns. Les valeurs manquantes donnent des indicateurs tous faux, sauf si dummy_na=True ajoute une colonne de valeurs manquantes. Pour une régression par les moindres carrés ordinaires avec une constante, drop_first=True supprime une colonne de catégorie redondante ; d’autres modèles peuvent conserver toutes les catégories. Avec une catégorie par ligne, la somme de toutes les indicatrices est égale à la constante 1, ce qui crée une dépendance linéaire.
Pour les cellules contenant plusieurs étiquettes, s.str.get_dummies(sep="|") découpe une valeur comme « Action|Comedy » en indicateurs distincts. Les intervalles obtenus par discrétisation peuvent aussi être transmis à get_dummies, ce qui donne une colonne par intervalle.
Points clés
- Vérifie les bornes des intervalles et les valeurs hors intervalle avec
cut. cutdétermine les intervalles ;qcutvise des groupes d’effectifs similaires.- La normalisation min-max et les scores z conservent les valeurs numériques sur une échelle modifiée.
clipécrête les valeurs sans supprimer de lignes.- Les colonnes indicatrices représentent l’appartenance aux catégories sans inventer d’ordre numérique.
- Traite explicitement les catégories manquantes lorsque leurs indicateurs comptent.
3Nettoyer les données textuelles et catégorielles
Les valeurs textuelles doivent avoir une orthographe et un espacement cohérents avant de pouvoir servir de catégories ou de clés. Applique des méthodes de chaînes à une colonne, extrais des parties structurées avec des expressions régulières et choisis un type catégoriel lorsqu’un petit ensemble d’étiquettes se répète. Les exemples relient le nettoyage du texte aux recherches de doublons et aux fusions, tout en montrant en quoi les codes stockés et l’ordre des catégories diffèrent des mots visibles dans une table.
3.1 Harmoniser les valeurs textuelles
Une personne reconnaît la même ville dans « Lisbon » précédé d’un espace, « lisbon » et « LISBON » suivi d’un espace. pandas voit trois chaînes différentes. Nettoyer une colonne textuelle fournit un ensemble cohérent de valeurs à comparer lors des décomptes, des recherches de doublons et des fusions ultérieurs.
Appliquer des méthodes de chaînes à une Series
L’expression Python "Lima ".strip() agit sur une seule chaîne. Pour une colonne, utilise l’accesseur .str : s.str.strip() supprime les espaces superflus de chaque valeur non manquante. s.lower() déclenche une AttributeError car la Series elle-même ne possède pas de méthode lower. Utilise s.str.lower().
pandas 3 infère normalement le type str pour le texte, en remplacement de l’ancien type par défaut object. Le type str contient du texte et des valeurs manquantes, avec NaN pour le texte manquant. Les méthodes de chaînes fonctionnent sur les deux types. Affecte du texte à une colonne str ; si un nombre doit y figurer sous forme de texte, convertis-le d’abord.
Combine les opérations de nettoyage compatibles et affecte le résultat :
df["city"] = df["city"].str.strip().str.lower()
Les trois écritures de Lisbon deviennent « lisbon ». strip() supprime les caractères d’espacement aux extrémités, pas les espaces à l’intérieur d’un nom. upper() met toutes les lettres en majuscules, tandis que title() met une majuscule à chaque mot et transforme « new york » en « New York ». Choisis une forme cohérente pour les clés et les décomptes.
Découper des chaînes structurées
Pour « Silva, Ana » et « Tanaka, Yui », s.str.split(", ") renvoie des listes comme ["Silva", "Ana"]. Ajoute expand=True pour produire des colonnes distinctes. Récupère une partie de chaque liste avec .str[0] ou .str.get(1).
Si seul le premier séparateur doit découper une valeur, utilise n=1. Découper « a,b,c » aux virgules avec n=1 donne « a » et « b,c ». Sans limite, le résultat comporte trois parties. Indique exactement le séparateur, y compris tout espace faisant partie du format.
Rechercher et filtrer
s.str.contains("lis", case=False) recherche le texte n’importe où en ignorant la casse. s.str.startswith("ID") vérifie le début ; s.str.endswith(".csv") vérifie la fin. Les résultats booléens peuvent servir à sélectionner des lignes :
mask = df["city"].str.contains("san", case=False, na=False)
selected = df[mask]
Pour le type str de pandas 3, le texte manquant donne False dans ces tests de recherche. Écrire na=False indique aussi clairement le traitement voulu lorsque tu utilises des données textuelles nullables. contains interprète par défaut un motif comme une expression régulière ; ajoute regex=False pour rechercher littéralement du texte contenant des caractères spéciaux.
Remplacer des parties et construire de nouvelles chaînes
s.str.replace("kg", "", regex=False) supprime « kg » partout où il apparaît. s.replace("kg", "") ne modifie que les cellules qui valent exactement « kg ». Cette distinction compte pour des valeurs comme « 12 kg ».
str.replace traite son texte de recherche littéralement par défaut. Pour « 3.5 kg », .str.replace(".", "", regex=False) supprime le point et donne « 35 kg ». Avec regex=True, le point est un motif correspondant à presque n’importe quel caractère et supprime tous les caractères dans cet exemple sur une seule ligne. N’utilise jamais cette modification pour analyser une mesure décimale.
s.str.len() compte les caractères ; une valeur manquante produit NaN et peut donner une colonne de nombres à virgule flottante. s.str[:3] extrait les trois premiers caractères. Pour combiner des colonnes, df["first"] + " " + df["last"] associe Ana et Silva sous la forme « Ana Silva » ; str.cat est une autre méthode d’association. Chaque opération renvoie un résultat : enregistre-le donc dans la colonne que tu souhaites utiliser.
Points clés
- Utilise
.strpour appliquer des méthodes textuelles à une Series. - Supprime les espaces superflus et harmonise la casse avant de comparer des clés textuelles.
- Maîtrise le résultat du découpage avec
expandetn. - Pour les caractères spéciaux, choisis explicitement une recherche littérale ou par expression régulière.
- Réaffecte le texte nettoyé pour conserver la modification.
3.2 Extraire les parties décrites par un motif textuel
Une expression régulière décrit un motif dans un texte. Elle peut reconnaître une quantité même lorsque le nombre de chiffres ou l’espacement varie. Commence par un petit motif dont tu peux expliquer les éléments.
Lire les éléments du motif
| Motif | Signification |
|---|---|
\d | Un chiffre |
\w | Un caractère de mot : lettre, chiffre ou trait de soulignement |
\s | Un caractère d’espacement |
[A-Z] | Une lettre majuscule de cet intervalle |
+ | Une ou plusieurs occurrences de l’élément précédent |
* | Zéro ou plusieurs occurrences de l’élément précédent |
? | L’élément précédent est facultatif |
{4} | Exactement quatre répétitions |
(…) | Un groupe de capture |
Écris les motifs Python sous forme de chaînes brutes, comme r"\d+", pour que Python conserve leurs barres obliques inverses. Par défaut, un point correspond à n’importe quel caractère sauf un saut de ligne. Échappe-le sous la forme r"\." pour trouver un vrai point. Pour une recherche de texte littéral, regex=False évite entièrement l’interprétation du motif.
Choisir la portion de texte qui doit correspondre
contains trouve un motif n’importe où, match commence au début et fullmatch exige que la valeur entière corresponde. Pour « 123a », s.str.contains(r"\d+") et s.str.match(r"\d+") réussissent, mais s.str.fullmatch(r"\d+") échoue. Utilise le test sur la chaîne entière pour vérifier un code complet. case=False ou flags=re.IGNORECASE après import re permet une recherche sans distinction de casse là où ces options sont prises en charge.
Capturer une mesure
Prends « Rice 5 kg », « Flour 2kg », « Salt » et « Beans 12 kg, 3 kg ». Le motif r"(\d+)\s*kg" signifie un ou plusieurs chiffres capturés dans un groupe, suivis de zéro ou plusieurs espaces puis de « kg ».
quantity = s.str.extract(r"(\d+)\s*kg", expand=False)
quantity = pd.to_numeric(quantity)
Les chaînes extraites sont « 5 », « 2 », une valeur manquante et « 12 ». La conversion donne les valeurs numériques 5.0, 2.0, NaN et 12.0. extract prend la première correspondance de chaque ligne, donc la deuxième quantité dans la description des haricots n’est pas incluse. Sans expand=False, un seul groupe renvoie un DataFrame à une colonne.
Les groupes nommés donnent des étiquettes aux sorties. s.str.extract(r"(?P<year>\d{4})-(?P<month>\d{2})") trouve « 2024-03 » dans « Report 2024-03 final » et renvoie les colonnes textuelles year et month. Le motif reconnaît la disposition des chiffres ; la conversion numérique est une étape distincte.
Trouver toutes les correspondances ou nettoyer à l’aide d’un motif
findall(r"\d+") donne une liste par ligne, notamment ["12", "3"] pour le texte sur les haricots et [] pour « Salt ». count(r"\d+") compte les correspondances. extractall donne une ligne par correspondance avec un niveau d’index supplémentaire nommé match.
Avec regex=True, s.str.replace(r"\s+", " ", regex=True) réduit les suites de caractères d’espacement à un seul espace. r"\D" désigne un caractère qui n’est pas un chiffre ; le supprimer transforme donc « +351 912-345-678 » en « 351912345678 ». Les formes majuscules \S et \W désignent de même les caractères qui n’appartiennent pas respectivement aux classes des caractères d’espacement et des caractères de mot.
La répétition est gloutonne par défaut. Dans "<b>x</b>", r"<.*>" va du premier symbole ouvrant au dernier symbole fermant. Supprimer cette correspondance supprime tout. Le motif non glouton r"<.*?>" correspond à chaque balise séparément et laisse « x ». Vérifie des exemples de résultats avant d’utiliser un motif sur toute une colonne.
Points clés
- Utilise des chaînes brutes pour conserver les barres obliques inverses des expressions régulières.
- Choisis
contains,matchoufullmatchselon la portion de texte visée. - Les groupes de capture renvoient du texte ; convertis séparément les nombres extraits.
extractprend la première correspondance ;findalletextractallconservent plusieurs correspondances.- Échappe les caractères spéciaux pour les rechercher littéralement dans une expression régulière.
- Vérifie les motifs gloutons sur des exemples comportant plusieurs correspondances possibles.
3.3 Stocker les étiquettes répétées sous forme de catégories
Une colonne contenant peu de valeurs répétées de nombreuses fois peut utiliser le type category. Celui-ci stocke les étiquettes distinctes une seule fois et représente chaque ligne par un petit code entier. La valeur visible reste l’étiquette.
Comprendre les catégories et les codes
Pour les tailles M, S, L, M, M, s.astype("category") infère les catégories L, M, S par ordre alphabétique. Les codes sont 1, 2, 0, 1, 1. Utilise s.cat.categories pour examiner les étiquettes et s.cat.codes pour examiner les identifiants. Un code de 0 désigne la première catégorie stockée ; ce n’est pas une quantité mesurée.
Les étiquettes répétées peuvent permettre d’économiser beaucoup de mémoire. Jusqu’à 126 catégories, les codes occupent chacun un octet ; à partir de 127 catégories, ils occupent deux octets. Dans une configuration pandas 3.1 avec PyArrow, trois noms de pays répétés sur 3 000 000 de lignes occupaient environ 3 Mo sous forme de données catégorielles, environ 42 Mo en str et environ 165 Mo en object. Le moteur de stockage du texte influe sur ces chiffres. Une colonne dont les valeurs sont presque toutes uniques ne tire aucun avantage du stockage d’une liste de catégories et d’un code par ligne.
Définir un ordre qui a un sens
L’ordre alphabétique des tailles place L avant M, puis S. Définis explicitement l’ordre réel des tailles :
size_type = pd.CategoricalDtype(["S", "M", "L"], ordered=True)
sizes = s.astype(size_type)
Le tri suit maintenant l’ordre S, M, L, les comparaisons comme sizes > "S" ont un sens, et sizes.max() vaut « L » lorsque L est présent. Pour des étiquettes non ordonnées comme les pays, les tests d’égalité fonctionnent, mais les comparaisons de supériorité déclenchent une TypeError. as_ordered() utilise la séquence existante des catégories ; examine-la avant de considérer que cet ordre a un sens.
Modifier les étiquettes autorisées
Tu ne peux pas affecter « XL » à une colonne catégorielle qui n’autorise que S, M et L. Affecte d’abord le résultat enrichi, sizes = sizes.cat.add_categories("XL"), puis affecte la nouvelle valeur.
Convertir du texte vers une liste fixe de catégories peut transformer les valeurs absentes de la liste en valeurs manquantes. pandas 3.1 avertit que cette conversion avec perte deviendra une erreur. Vérifie les valeurs sources avec value_counts() avant la conversion, en particulier après avoir nettoyé les graphies.
Les méthodes .cat ont des fonctions différentes :
rename_categories({"S": "small"})modifie une étiquette tout en conservant ses éléments.remove_categories("L")supprime une étiquette autorisée et rend manquantes les valeurs L existantes.set_categories([...])remplace toute la liste des catégories.reorder_categories([...], ordered=True)modifie l’ordre sans changer les étiquettes autorisées.remove_unused_categories()supprime les étiquettes auxquelles aucun élément n’appartient actuellement.
value_counts() affiche toutes les catégories autorisées, y compris celles qui ne comptent aucune observation. Avec un type S/M/L contenant uniquement S et M, L apparaît tout de même avec un effectif de 0. Cela fait apparaître un groupe vide dont les données textuelles ordinaires ne stockent pas l’étiquette.
Garder les catégories utiles pour la suite
cut produit des intervalles catégoriels, et get_dummies convertit l’appartenance aux catégories en colonnes indicatrices. Fournir à un modèle les codes de pays non ordonnés sous forme de nombres imposerait un ordre et des distances artificiels. Les indicatrices évitent cette interprétation.
La concaténation de colonnes catégorielles dont les listes de catégories diffèrent fait normalement perdre le type catégoriel. Harmonise d’abord leurs listes de catégories ou utilise pd.concat(..., union_categories=True) dans pandas 3.1 lorsque tu souhaites réunir les listes. Examine à la fois le type obtenu et l’ordre des catégories.
Points clés
- Les colonnes catégorielles stockent une liste d’étiquettes et des identifiants entiers.
- Définis explicitement l’ordre des catégories lorsqu’un classement a un sens.
- Ajoute une catégorie avant d’affecter une nouvelle étiquette.
- Supprimer une catégorie utilisée rend ses valeurs manquantes.
- Utilise des indicatrices pour les catégories non ordonnées dans les modèles numériques.
- Harmonise les listes de catégories ou réunis-les volontairement avant la concaténation.
4Combiner des DataFrame
Combiner des tables peut ajouter des informations, ajouter des observations ou compléter des valeurs manquantes depuis une source de secours. Ce sont des tâches différentes. Fais correspondre des clés explicites avec merge, utilise les étiquettes d’index avec join et combine_first, et empile des parties compatibles avec concat. Avant de te fier à un résultat, prévois quelles lignes doivent être conservées et combien de correspondances chaque clé doit produire ; les exemples montrent pourquoi une augmentation inattendue commence souvent par une clé de correspondance répétée.
4.1 Prévoir ce qu’une fusion conservera
Une fusion fait correspondre des lignes à l’aide de valeurs de clé et place leurs informations côte à côte. La clé doit désigner la même chose dans les deux tables, comme l’identifiant du client sur une commande et l’identifiant du client dans une table de correspondance.
Nommer la clé et choisir la jointure
Utilise orders.merge(customers, on="customer_id"). Sans on, pandas utilise tous les noms de colonnes communs aux deux tables. Une colonne commune sans rapport comme date pourrait alors empêcher des correspondances valides entre clients.
Supposons que les commandes portent les identifiants de clients 10, 20, 20, 30, 50. La table des clients contient une ligne pour chacun des identifiants 10, 20, 30, 40.
how | Ce qui est conservé | Nombre de lignes du résultat |
|---|---|---|
"inner" | Les clés correspondantes des deux côtés | 4 |
"left" | Chaque ligne de gauche et ses correspondances | 5 |
"right" | Chaque ligne de droite et ses correspondances | 5 |
"outer" | Les clés de l’un ou l’autre côté | 6 |
"cross" | Chaque paire de lignes gauche/droite | 20 |
La jointure interne est celle par défaut. Dans une fusion à gauche, les détails du client 50 sont manquants. Une fusion à droite inclut le client 40 sans commande, ainsi que les deux commandes du client 20. Une fusion externe complète inclut les deux clés sans correspondance. Une fusion croisée n’a pas besoin de clé car elle associe volontairement toutes les lignes entre elles. pandas 3 fournit aussi left_anti et right_anti pour les lignes dont la clé n’a pas de correspondance de l’autre côté.
Vérifier le nombre de correspondances possibles par ligne
Deux lignes à gauche pour la clé 20 et trois lignes à droite pour la clé 20 produisent six paires. La fusion ne choisit pas une seule ligne de droite. Dans l’exemple, ajouter une deuxième ligne de correspondance pour le client 20 fait passer le résultat de la fusion interne de quatre à six lignes.
Indique la relation prévue avec validate :
merged = orders.merge(
customers, on="customer_id", how="left",
validate="many_to_one"
)
Cela autorise plusieurs commandes par client mais exige que les identifiants de clients à droite soient uniques. Une clé répétée à droite déclenche une MergeError. one_to_one exige l’unicité des deux côtés ; one_to_many l’exige à gauche. many_to_many autorise les répétitions des deux côtés et ne vérifie pas l’unicité.
Examiner les lignes sans correspondance
Une fusion externe complète avec indicator=True ajoute _merge. Ici, les effectifs sont de quatre lignes both, une ligne left_only et une ligne right_only. Ce sont des lignes, pas des clés distinctes : des commandes répétées peuvent produire plusieurs lignes both pour un même client.
Pour compter les clés distinctes sans correspondance du côté des commandes, utilise m.loc[m["_merge"] == "left_only", "customer_id"].nunique(). Examiner les lignes peut révéler des entrées manquantes dans la table de correspondance ou du texte incohérent.
Maîtriser les noms et les formats des clés
Si les clés ont des noms différents, utilise left_on="customer_id", right_on="id". Les deux colonnes clés restent disponibles. Plusieurs clés peuvent être comparées ensemble avec on=["city", "year"] ; les deux valeurs doivent concorder.
Les noms communs aux colonnes qui ne sont pas des clés reçoivent _x et _y. Choisis des suffixes explicites comme suffixes=("_order", "_ship") pour que les provenances restent claires.
Les clés doivent avoir des types de données compatibles et des valeurs égales. La valeur numérique 1 peut correspondre à la valeur numérique 1,0, mais des colonnes clés entières et textuelles peuvent déclencher une erreur de fusion. Convertis leurs formats de façon réfléchie. « ana » et « Ana » suivi d’un espace sont des textes différents ; harmonise la casse et les espaces aux extrémités avant la fusion lorsqu’ils désignent la même personne.
Les clés manquantes doivent aussi être examinées : pandas fait correspondre les clés manquantes d’un côté à celles de l’autre. Si les deux côtés contiennent plusieurs lignes de ce type, ces correspondances peuvent elles aussi se multiplier.
Points clés
- Indique explicitement les clés de fusion.
- Choisis le type de jointure selon les lignes sources qui doivent être conservées.
- Des clés répétées produisent toutes les paires correspondantes.
- Utilise
validatepour vérifier la relation prévue entre les clés. - Utilise une fusion externe complète avec un indicateur pour examiner les lignes sans correspondance.
- Vérifie les valeurs et les formats des clés ainsi que les suffixes avant d’utiliser le résultat.
4.2 Combiner les valeurs dont les étiquettes d’index correspondent
Un index peut contenir la clé que tu souhaites faire correspondre. pandas utilise ces étiquettes pour joindre des tables, compléter des valeurs manquantes ou additionner deux Series. La position des lignes ne détermine pas à elle seule les correspondances.
Effectuer une jointure sur les étiquettes d’index
left.join(right) fait correspondre les deux index et effectue par défaut une jointure à gauche. À l’inverse, merge effectue par défaut une jointure interne. Tu peux aussi écrire left.merge(right, left_index=True, right_index=True) lorsque les deux clés se trouvent dans l’index.
Supposons que stations possède les étiquettes d’index A, B, C et les altitudes 120, 850, 15 m. Une table de relevés possède les étiquettes d’index de stations A, B, B, D. readings.join(stations) conserve quatre lignes et ajoute les altitudes 120, 850, 850 et NaN. Les deux relevés B reçoivent tous deux l’altitude de B. Avec how="inner", seuls les trois relevés A/B sont conservés.
Si la table des relevés conserve les identifiants de stations dans une colonne ordinaire, utilise readings.join(stations, on="station"). La colonne de gauche correspond à l’index de droite. La forme équivalente avec une fusion est readings.merge(stations, left_on="station", right_index=True, how="left").
Indiquer clairement l’emplacement de la clé
set_index("station") déplace la colonne des stations dans l’index. reset_index() la rétablit comme colonne ordinaire. Ces opérations permettent de choisir une disposition qui rend la correspondance facile à examiner. left.join([t1, t2]) peut joindre en une fois plusieurs tables partageant des étiquettes d’index.
Si les deux tables jointes contiennent une colonne qui n’est pas une clé, comme source, join déclenche une ValueError sauf si tu distingues les noms. Dans pandas 3.1, écris suffixes=("_left", "_right") ; cela remplace les anciens arguments lsuffix et rsuffix. Les suffixes conservent les deux versions sans décider quelle valeur fait autorité.
Compléter les valeurs manquantes depuis une source de secours
a.combine_first(b) conserve les valeurs connues de a, remplace ses valeurs manquantes par celles de b aux étiquettes correspondantes et inclut les étiquettes présentes uniquement dans b.
| Étiquette | a | b | a.combine_first(b) |
|---|---|---|---|
| a | 1 | 10 | 1 |
| b | NaN | 20 | 20 |
| c | 3 | 30 | 3 |
| d | absent | 40 | 40 |
Le résultat conserve 1 et 3 car la première source les connaît déjà. Il utilise 20 pour remplacer la valeur manquante et ajoute l’étiquette d avec 40. Inverser l’appel change la source prioritaire. C’est utile lorsqu’une source principale doit avoir priorité sur une source de secours, même si leurs lignes sont dans des ordres différents.
Reconnaître l’alignement dans les calculs
Soit x avec a = 5 et b = 7 ; soit y avec b = 1 et c = 2. x + y donne b = 8, avec des résultats manquants pour a et c car il manque un opérande pour chacun. L’opération n’additionne pas la première valeur de x à la première valeur de y.
x.add(y, fill_value=0) fournit zéro pour le côté manquant et produit a = 5, b = 8, c = 2. Utilise cette règle lorsqu’une contribution absente doit compter pour zéro. L’alignement des étiquettes est le même principe d’organisation derrière ces opérations, mais leurs règles sur les valeurs diffèrent : join ajoute des colonnes, combine_first complète les valeurs manquantes et les calculs opèrent sur les valeurs correspondantes.
Points clés
joineffectue par défaut une jointure à gauche sur l’index ;mergeeffectue par défaut une jointure interne.- Dans
join(on="station"), la colonne de gauche correspond à l’index de droite. - Utilise des suffixes pour distinguer les colonnes de même nom qui ne sont pas des clés.
combine_firstdonne la priorité aux valeurs connues de l’objet qui appelle la méthode.- Les calculs s’alignent sur les étiquettes ;
fill_valuedétermine le traitement des contributions manquantes.
4.3 Empiler des tables compatibles avec concat
Les fichiers mensuels contiennent généralement davantage de lignes correspondant au même type d’observation. La concaténation rassemble ces parties dans une seule table. Elle aligne les étiquettes sur l’autre axe ; elle ne recherche pas les valeurs correspondantes des clés de clients ou de commandes.
Empiler les lignes et aligner les colonnes
pd.concat([jan, feb]) empile les lignes car l’option par défaut est axis=0. Supposons que janvier contienne trois trajets avec les colonnes trip et km, tandis que février contient deux trajets avec trip, km et note. Le résultat comporte cinq lignes et trois colonnes. Les cellules note manquantes de janvier deviennent NaN.
join="outer" est l’option par défaut : elle conserve l’union des noms de colonnes. join="inner" ne conserve que les noms communs ; le résultat contient donc cinq lignes et les deux colonnes trip et km. Il inclut toujours les cinq observations ; le réglage de jointure agit sur l’autre axe.
L’ordre des colonnes dans les parties ne détermine pas la correspondance. Ce sont les noms exacts qui la déterminent. Si une partie utilise km et l’autre Km, le résultat contient deux colonnes partiellement vides. Renomme les en-têtes avant la concaténation.
Décider de la signification des étiquettes de lignes
Les index d’origine sont conservés par défaut. Avec les index de départ 0, 1, 2 et 0, 1, le résultat répète les étiquettes 0 et 1. result.loc[0] sélectionne deux lignes. Utilise ignore_index=True lorsque ces nombres n’ont pas de signification et que tu veux de nouvelles étiquettes de 0 à 4.
Lorsque la provenance compte, utilise un niveau d’index externe :
result = pd.concat(
[jan, feb], keys=["jan", "feb"], names=["month", "row"]
)
result.loc["feb"] sélectionne maintenant les deux lignes de février. keys conserve la provenance dans un MultiIndex. Dans pandas 3, combiner keys avec ignore_index=True déclenche une ValueError ; choisis des étiquettes de provenance ou un nouvel index simple pour cette opération.
Placer les colonnes côte à côte
pd.concat([x, y], axis=1) aligne les lignes selon les étiquettes d’index. Pour x avec a = 1, b = 2 et y avec b = 3, c = 4, le résultat comporte les lignes a, b, c. La colonne x est manquante pour c et y est manquant pour a. Avec join="inner", seul b reste.
| Opération | Ajout selon | Étiquettes alignées selon |
|---|---|---|
concat(..., axis=0) | Les lignes | Les noms de colonnes |
concat(..., axis=1) | Les colonnes | Les index de lignes |
merge(..., on="id") | Les paires de lignes correspondantes | Les valeurs de la colonne clé |
Vérifier le stockage et rassembler efficacement les parties
Une colonne mélangeant des valeurs numériques et du texte peut devenir de type object. Si des données NumPy ordinaires int64 acquièrent une valeur manquante, elles deviennent float64 ; le type nullable "Int64" de pandas peut conserver des entiers avec <NA>. Harmonise les types avant de combiner les données lorsque la colonne possède un type défini.
DataFrame.append a été supprimé dans pandas 2.0. Pour de nombreux fichiers, rassemble les DataFrame dans une liste et appelle pd.concat une seule fois après la boucle. Reconstruire un résultat qui grandit à chaque itération recopie sans cesse les données accumulées et devient lent.
Vérifie que la longueur d’une concaténation de lignes est égale à la somme des longueurs des entrées. Examine ensuite les noms de colonnes, les nombres de valeurs manquantes et les types de données.
Points clés
- La concaténation de lignes aligne les noms de colonnes et additionne les nombres de lignes des entrées.
joinchoisit les étiquettes communes ou toutes les étiquettes sur l’autre axe.- Utilise
ignore_indexpour des étiquettes sans importance oukeyspour conserver la provenance. - La concaténation de colonnes aligne les index de lignes.
- Rassemble d’abord les nombreuses parties et concatène-les une seule fois.
5Remodeler les données avec des index hiérarchiques, pivot et melt
Les mêmes mesures peuvent être disposées en lignes, en colonnes ou en niveaux d’index. Utilise un MultiIndex pour désigner les observations par plusieurs clés, puis déplace ces clés avec stack et unstack ou avec pivot et melt. Suis les étiquettes qui identifient une cellule et vérifie si elles sont uniques. Le remodelage devient ainsi prévisible et tu peux distinguer une combinaison absente d’un zéro mesuré ou d’une paire d’enregistrements qui nécessite une agrégation explicite.
5.1 Sélectionner des lignes avec plusieurs niveaux d’index
Un MultiIndex donne plusieurs étiquettes à chaque ligne. Une ligne de ventes peut être identifiée à la fois par la ville et l’année, sous la forme d’un tuple comme ("Osaka", 2024). Chaque étiquette appartient à un niveau, et l’ordre de ces niveaux compte pour la sélection.
Construire et nommer l’index
df.set_index(["city", "year"]) déplace ces colonnes dans l’index. pd.MultiIndex.from_product([["Lima", "Osaka"], [2024, 2025]], names=["city", "year"]) construit toutes les combinaisons des étiquettes fournies. La concaténation avec keys ajoute également un niveau.
Pour les exemples, sales contient ces paires d’index et ces valeurs :
| city | year | sales |
|---|---|---|
| Osaka | 2024 | 120 |
| Osaka | 2025 | 135 |
| Lima | 2024 | 80 |
| Lima | 2025 | 95 |
Après la définition des deux niveaux d’index, df.index.names vaut ["city", "year"]. rename_axis(["town", "yr"]) modifie les noms des niveaux sans modifier leurs valeurs.
Sélectionner une étiquette externe ou un tuple complet
df.loc["Osaka"] sélectionne les deux lignes d’Osaka. Le niveau de la ville sélectionnée disparaît, laissant 2024 et 2025 comme index. df.loc[("Lima", 2025), "sales"] sélectionne une cellule et renvoie 95.
Une seule étiquette passée à loc est recherchée dans le niveau le plus externe. df.loc[2024] cherche donc une ville nommée 2024 et déclenche une KeyError dans cette table. Pour sélectionner une année pour toutes les villes, utilise df.xs(2024, level="year"). Cette méthode renvoie 120 pour Osaka et 80 pour Lima, avec la ville comme index restant.
Pour une sélection plus générale, df.loc[pd.IndexSlice[:, 2025], :] conserve toutes les villes pour l’année 2025. Les deux-points en première position désignent toutes les étiquettes de ce niveau ; les derniers deux-points sélectionnent toutes les colonnes.
Trier avant d’extraire des tranches d’étiquettes
La sélection d’une étiquette exacte ne nécessite pas un index entièrement trié, mais l’extraction d’une tranche d’étiquettes exige un tri approprié. Utilise df.sort_index() avant df.loc["Lima":"Osaka"]. Un MultiIndex non trié peut déclencher une UnsortedIndexError pour une telle tranche.
sort_index() trie tous les niveaux dans leur ordre actuel : les villes viennent donc en premier, puis les années au sein de chaque ville. sort_index(level="year") trie selon le niveau nommé. swaplevel("city", "year") place l’année en position externe ; fais suivre cette opération de sort_index() pour regrouper et trier la nouvelle disposition. Permuter les positions des niveaux ne trie pas les lignes à lui seul.
Replacer les étiquettes dans les colonnes
reset_index() rétablit les deux niveaux comme colonnes. reset_index(level="year") ne rétablit que l’année et laisse la ville comme index. Ces opérations permettent de préparer une table pour une fusion ou un enregistrement sans perdre ses valeurs d’identification.
Les colonnes peuvent elles aussi comporter plusieurs niveaux. Un remodelage avec des valeurs de ventes et d’effectifs peut produire les étiquettes de colonnes ("sales", 2024) et ("staff", 2025). df["sales"] sélectionne toutes les colonnes situées sous l’étiquette de niveau supérieur correspondant aux ventes.
Pour obtenir un total par ville, df.groupby(level="city")["sales"].sum() donne 175 pour Lima et 255 pour Osaka. Utilise le regroupement pour calculer cet indicateur ; l’ancien argument sum(level="city") a été supprimé dans pandas 2.0.
Points clés
- Un tuple identifie une étiquette MultiIndex complète à travers les niveaux.
- Une sélection
locavec une seule étiquette commence au niveau le plus externe. - Utilise
xsouIndexSlicepour sélectionner un niveau interne. - Trie l’index avant d’extraire une tranche d’étiquettes.
- Permute les niveaux pour changer leurs rôles et réinitialise-les pour rétablir les colonnes.
- Utilise
groupby(level=...)pour calculer des indicateurs par niveau d’index.
5.2 Déplacer les étiquettes entre l’index et les colonnes
stack et unstack modifient l’emplacement des étiquettes. Les valeurs conservent leur combinaison d’identification, mais la table peut faire apparaître des combinaisons pour lesquelles aucune observation n’existait.
Empiler les étiquettes de colonnes dans l’index
Supposons qu’un DataFrame au format large ait les villes Osaka et Lima comme index et les années 2024 et 2025 comme colonnes. Osaka possède les valeurs 120 et 135 ; Lima possède 80 et 95. Nomme les axes city et year pour que leur signification reste visible.
long = wide.stack() déplace les étiquettes d’années dans un nouveau niveau d’index interne. Avec ces colonnes à un seul niveau, le résultat est une Series contenant quatre valeurs :
("Osaka", 2024)donne 120.("Osaka", 2025)donne 135.("Lima", 2024)donne 80.("Lima", 2025)donne 95.
Les étiquettes de villes se répètent car chaque ville possède désormais une ligne par année. L’empilement n’a pas additionné les valeurs ni créé de mesures supplémentaires.
Désempiler un niveau d’index dans les colonnes
long.unstack() déplace le niveau d’index le plus interne, l’année, dans les colonnes et retrouve la disposition au format large. long.unstack("city") déplace la ville à la place, ce qui produit des années en lignes et des villes en colonnes. Une position numérique de niveau comme unstack(0) peut sélectionner le même niveau, mais un nom rend l’intention plus facile à lire.
| Opération | Déplacement des étiquettes |
|---|---|
stack() | Un niveau de colonne devient un niveau d’index interne |
unstack() | Un niveau d’index devient un niveau de colonne |
Si l’entrée possède des colonnes hiérarchiques, empiler un niveau peut laisser un autre niveau comme colonnes. Pour des colonnes comme ("sales", 2024) et ("staff", 2024), stack("year") renvoie un DataFrame avec des colonnes de ventes et d’effectifs. Empiler tous les niveaux de colonnes renvoie une Series.
Garder les combinaisons manquantes visibles
Supposons maintenant que la Series au format long ne contienne pas d’entrée pour Lima en 2025. Le désempilement crée une table rectangulaire ville par année et introduit donc NaN à cette position. Les valeurs entières ordinaires deviennent des nombres à virgule flottante lorsque cette cellule manquante nécessite un marqueur de valeur manquante de ce type.
unstack(fill_value=0) peut remplacer par zéro une combinaison nouvellement absente. Utilise cette option uniquement si l’absence signifie zéro, par exemple aucune vente enregistrée dans un jeu complet d’événements de vente. Une observation manquante d’un capteur est inconnue et doit rester manquante.
Dans pandas 3, stack() conserve les cellules manquantes. Empiler la table incomplète de 2 × 2 renvoie donc quatre entrées, dont NaN. Ajoute .dropna() si tu ne veux que les trois valeurs connues. Supprimer les valeurs manquantes modifie les combinaisons qui restent représentées : vérifie donc la longueur du résultat.
Résoudre d’abord les combinaisons en double
Le désempilement nécessite une seule valeur pour chaque combinaison complète d’index. Deux entrées étiquetées ("Lima", 2025) se disputent la même cellule de sortie et déclenchent ValueError: Index contains duplicate entries, cannot reshape.
Utilise long.index.duplicated() pour examiner les étiquettes complètes répétées, ou vérifie les colonnes clés correspondantes avant de définir l’index. Détermine si les lignes sont des copies accidentelles ou des observations distinctes qu’il faut combiner. Les supprimer ou les agréger est une décision relative aux données ; unstack ne choisit pas de règle à ta place.
Points clés
stackdéplace les étiquettes de colonnes vers un niveau d’index interne ;unstackdéplace les étiquettes d’index vers les colonnes.- Choisis explicitement le niveau lorsque celui par défaut n’est pas celui dont tu as besoin.
- Les combinaisons absentes apparaissent sous forme de cellules manquantes lors du passage au format large.
- Dans pandas 3, l’empilement conserve les valeurs manquantes sauf si tu les supprimes ensuite.
- Chaque combinaison complète d’index doit être unique pour permettre le désempilement.
5.3 Passer du format long au format large et inversement
Au format long, des colonnes d’identification accompagnent une colonne de valeurs. Au format large, les mesures sont réparties sur plusieurs colonnes, par exemple une colonne par année. Choisis la disposition qui facilite la tâche suivante : les tables au format long conviennent au filtrage et au regroupement, tandis que les tables au format large facilitent les comparaisons côte à côte.
Pivoter des paires uniques dans des cellules
Une table au format long contenant les colonnes city, year et sales passe au format large avec df.pivot(index="city", columns="year", values="sales"). Les étiquettes de villes forment les lignes, les années les colonnes et les ventes remplissent les cellules. Cette opération équivaut à df.set_index(["city", "year"])["sales"].unstack().
Les ventes d’Osaka de 120 et 135 en 2024 et 2025 deviennent deux cellules d’une même ligne. Les valeurs 80 et 95 de Lima forment la deuxième ligne. Inverser les arguments index et columns transpose cette disposition. Omettre values pivote toutes les colonnes de données restantes et peut créer des colonnes hiérarchiques, par exemple un niveau de ventes et un niveau d’effectifs au-dessus des années.
Déterminer si les répétitions sont des erreurs ou des observations
pivot réorganise les valeurs et ne peut pas les combiner. Deux lignes pour Lima en 2025 exigeraient deux valeurs dans une même cellule de sortie et déclencheraient donc une ValueError. Compte les paires répétées avec df.duplicated(subset=["city", "year"]).sum().
Si des observations distinctes doivent être combinées, utilise pivot_table avec une agrégation choisie. Pour les valeurs 95 et 105 de Lima en 2025, sa moyenne par défaut donne 100.0. Avec aggfunc="sum", la cellule vaut 200. Si chaque paire aurait dû apparaître une seule fois, conserve pivot pour qu’il révèle une erreur dans les données au lieu de calculer un indicateur sans avertissement.
Dépivoter les colonnes de mesures en lignes
Supposons qu’un CSV fournisse les colonnes city, 2023, 2024 et 2025. Les valeurs d’Osaka sont 110, 120, 135 ; celles de Lima sont 70, 80, 95. Dépivote les colonnes d’années :
long = wide.melt(
id_vars="city", var_name="year", value_name="sales"
)
id_vars reste en place et se répète. Chaque étiquette de colonne de mesures devient une valeur d’année ; chaque cellule devient une valeur de ventes. Deux lignes et trois colonnes de mesures produisent six lignes au format long, dont une comme Osaka, « 2023 », 110. Les cellules de mesures manquantes deviennent elles aussi des lignes, sauf si tu les supprimes ensuite.
Comme ces étiquettes de colonnes proviennent du texte CSV, les années obtenues sont du texte. Utilise long["year"] = long["year"].astype(int) avant d’effectuer des calculs avec elles. Des étiquettes de colonnes entières en entrée donneraient déjà des années entières.
Maîtriser les éléments dépivotés et rétablir la forme
value_vars=["2024", "2025"] limite le dépivotage à ces colonnes. Oublier id_vars peut dépivoter les noms de villes dans la même colonne de valeurs que les mesures. Distingue toujours les identifiants des colonnes qui contiennent les valeurs.
Sans noms explicites, la colonne de valeurs s’appelle value. La colonne des variables hérite de wide.columns.name, ou s’appelle variable si ce nom est vide. Des paramètres var_name et value_name explicites rendent le résultat plus facile à utiliser.
Pivote à nouveau les six lignes avec index="city", columns="year", values="sales" pour rétablir les trois colonnes d’années. Après le pivotement, la ville est l’index et l’axe des colonnes s’appelle year. reset_index() rétablit la ville comme colonne, et rename_axis(columns=None) supprime le nom de l’axe des colonnes. Vérifie la forme et les étiquettes avant de fusionner ou d’enregistrer la table.
Points clés
- Le format long place les étiquettes de mesures dans les lignes ; le format large les place dans les colonnes.
pivotnécessite des paires ligne/colonne uniques et n’effectue aucune agrégation.pivot_tablecombine les paires répétées à l’aide de l’agrégation choisie.meltrépète les identifiants et crée une ligne par cellule de mesure.- Vérifie les types des étiquettes de colonnes lorsqu’elles deviennent des valeurs.
- Réinitialise les index et les noms d’axes lorsqu’une table de sortie sans index hiérarchique est nécessaire.
Préparer les données avec pandas : exemples
1Nettoyer des relevés sans perdre leur signification
16 étapes
- 1IntroductionDéterminer la signification de chaque valeur manquante
Une table météorologique contient quatre villes et deux colonnes de mesures : la température en °C et les précipitations en mm. Certains relevés sont manquants. Tu vas repérer ces valeurs manquantes, décider quelles lignes sont utilisables et distinguer un enregistrement répété d’une observation réellement différente. Le résultat utile est une table dont les valeurs restantes ont toujours la signification que tu leur attribues. Utilise
import pandas as pdetimport numpy as nppour le code. - 2ExplicationReconnaître le marqueur de valeur manquante
Une valeur manquante peut apparaître sous la forme
NaN,NaToupd.NA, selon son type de données.Noneest lui aussi reconnu comme manquant.Utilise
df.isna()pour créer un tableau booléen contenantTrueà chaque emplacement manquant. Une comparaison avecnp.nanne repère pas ces valeurs car NaN est différent même de lui-même. La méthode de détection permet d’effectuer la même vérification sur des colonnes numériques, textuelles et de dates et heures. - 3ExempleCompter les valeurs météorologiques manquantes
Lima a une température de 18 et des précipitations de 0. La température d’Oslo manque, mais ses précipitations valent 4. Pune a une température de 31 et ses précipitations manquent. Les deux relevés de Kyiv manquent. Tous les noms de villes sont connus.
df.isna().sum()donne 0 ville, 2 températures et 2 valeurs de précipitations manquantes.df.isna().mean()donne les proportions manquantes 0, 0.5 et 0.5 car chaque colonne contient quatre entrées. - 4Point cléDistinguer les cellules des lignes
Kyiv possède deux cellules manquantes, tandis qu’Oslo et Pune en possèdent une chacune. Il y a quatre cellules manquantes mais seulement trois lignes concernées.
df.isna().sum().sum()compte les cellules.df.isna().any(axis=1).sum()indique d’abord si chaque ligne comporte une valeur manquante, puis compte ces lignes. Leanyappliqué par ligne évite de compter Kyiv deux fois. - 5DéfiTrouver un code caché de valeur manquante
Une colonne de capteur contient 0, 7, -999 et
NaN. Sa documentation indique que -999 signifie que le capteur était éteint. Combien de valeurs doivent rester connues après le nettoyage ?---reveal---
Deux : 0 et 7. Remplace le code documenté -999 par un marqueur de valeur manquante, puis utilise à nouveau
isna(). Zéro est ici un relevé réel. Traiter tous les zéros comme des valeurs manquantes supprimerait une valeur connue en même temps que les relevés indisponibles. - 6ExempleConserver les lignes qui possèdent une température
Supposons que l’analyse nécessite la température mais puisse tolérer des précipitations inconnues. Utilise
clean = df.dropna(subset=["temp_c"]). Cela conserve Lima et Pune.Le
dropna()par défaut ne conserverait que Lima car il vérifie toutes les colonnes.thresh=2conserverait aussi Oslo, dont la ville et les précipitations sont connues. Choisis la règle qui exprime les colonnes réellement nécessaires à l’analyse. - 7ExempleMarquer les estimations avant le remplacement
Pour une analyse des précipitations qui conserve toutes les villes, pars des quatre lignes d’origine. Avant de remplacer les températures manquantes, enregistre
df["temp_missing"] = df["temp_c"].isna().Les températures connues 18 et 31 ont une moyenne de 24,5. Écris
df["temp_c"] = df["temp_c"].fillna(df["temp_c"].mean())pour remplacer les deux valeurs manquantes. L’indicateur enregistré permet toujours d’identifier les relevés d’Oslo et de Kyiv comme des estimations. - 8ConseilChoisir l’estimation selon sa signification
Le remplacement par la moyenne utilise les relevés connus comme estimation simple, mais réduit la dispersion apparente. La médiane est moins sensible aux relevés extrêmes. Remplacer par zéro affirme autre chose : la quantité manquante était nulle.
Un capteur de pluie éteint ne prouve pas que les précipitations étaient nulles. Utilise des valeurs de remplacement par colonne compatibles avec leurs types de données, par exemple un dictionnaire contenant des nombres pour les champs numériques et du texte pour les champs textuels.
- 9LienUtiliser l’ordre uniquement lorsqu’il apporte une information
La propagation vers l’avant copie la dernière valeur connue dans une case manquante ; la propagation vers l’arrière utilise la valeur connue suivante. Avec 12,
NaN,NaN, 15,ffill(limit=1)donne 12, 12,NaN, 15.L’interpolation estime quant à elle les valeurs entre des positions connues : 10,
NaN,NaN, 16 devient 10, 12, 14, 16. Ces méthodes conviennent à des relevés dont l’ordre a un sens, pas à une liste de villes sans rapport. - 10DéfiConserver les lignes utilisables sans affirmer qu’il n’a pas plu
Trois enregistrements contiennent A/19/2, B/21/
NaNet C/NaN/5 pour ville/température/précipitations. Tu dois comparer les températures et tu ne peux pas estimer les précipitations manquantes. Quelles lignes et quelles valeurs dois-tu conserver ?---reveal---
Conserve A et B en vérifiant la colonne de température avec
dropna(subset=["temp_c"]). Laisse les précipitations de B manquantes. Supprimer les lignes selon toutes les colonnes ferait perdre la température utilisable de B ; remplacer ses précipitations par zéro ajouterait une mesure non justifiée. - 11ExempleComparer les enregistrements complets
Une table de commandes contient les identifiants 101, 102, 102, 103, 104, 104. Les deux lignes 102 sont identiques. Les deux lignes 104 diffèrent par leur poids enregistré : 0,5 kg et 0,8 kg.
df.duplicated().sum()indique une copie supplémentaire de ligne complète.drop_duplicates()laisse cinq lignes car les enregistrements 104 différents ne sont pas des copies exactes. Les étiquettes d’index n’influent pas sur cette comparaison. - 12ExplicationChoisir une clé et une version à conserver
Comparer uniquement
order_idmarque le deuxième 102 et le deuxième 104 comme des répétitions, soit deux copies supplémentaires de clés. La question est maintenant de savoir quelle version représente chaque commande.keep="last"choisit la dernière dans l’ordre actuel des lignes. Pour que cela signifie la plus récente, trie d’abord selon un champ de mise à jour.keep=Falsesupprime tous les membres des groupes répétés et écarterait donc les deux enregistrements 104. - 13DéfiConserver l’enregistrement le plus récent
L’article H possède les mises à jour 1, 4, 2 et les poids 3, 6, 5 kg dans cet ordre d’entrée. Comment conserver son enregistrement le plus récent et quel poids reste ?
---reveal---
Trie
updatedpar ordre croissant, puis utilisedrop_duplicates(subset="item", keep="last"). La mise à jour la plus récente est 4, donc 6 kg est conservé. Conserver la dernière ligne d’entrée sans trier sélectionnerait la mise à jour 2 et garderait à tort 5 kg. - 14ConseilStandardiser avant de vérifier l’identité
Les clés textuelles « Lisbon » précédée d’un espace, « lisbon » et « LISBON » suivie d’un espace ne correspondent pas exactement. Supprime les espaces aux extrémités et mets-les en minuscules lorsque ces graphies désignent la même ville. Examine ensuite les clés répétées.
L’objectif de la table détermine si une répétition est valide : de nombreuses commandes peuvent partager un client, mais une table de correspondance censée fournir une ligne de détails par client nécessite des clés uniques. Supprimer des commandes valides ne peut pas corriger une clé répétée dans la table de correspondance.
- 15DéfiRelier le nettoyage du texte au choix des enregistrements
Des enregistrements de clients ont pour clés « emi » entourée d’espaces et « EMI », pour mises à jour 2 et 5, et pour soldes 10 et 14. L’ancien solde est manquant dans un troisième enregistrement sans rapport. Tu as besoin de l’enregistrement le plus récent par client. Que faut-il faire avant tout remplacement de solde manquant ?
---reveal---
Standardise les clés, trie par mise à jour et conserve la dernière ligne par clé nettoyée. Les deux graphies de Emi deviennent un seul client avec un solde de 14. Résous d’abord l’identité des enregistrements pour que les versions obsolètes n’influent pas sur une statistique de remplacement ultérieure.
- 16RécapitulatifVérifier le résultat par rapport à la décision
Après le nettoyage, compare le nombre de lignes, le nombre de valeurs manquantes et l’unicité des clés au résultat attendu. Un indicateur de valeurs manquantes rend les estimations visibles ; une recherche de doublons par clé après tri permet de voir la version d’enregistrement choisie.
Enregistre les objets renvoyés par affectation directe. Avec la copie à l’écriture de pandas 3, un appel
inplacechaîné sur une colonne sélectionnée ne modifie pas son DataFrame parent.
2Transformer des codes et des mesures
15 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionChoisir la signification du résultat
- 2ExempleTraduire ou modifier une valeur
- 3ExempleConvertir le texte après avoir nettoyé son format
- 4Point cléDistinguer les en-têtes des cellules
- 5DéfiTrouver l’origine d’une nouvelle valeur manquante
- 6ExempleLire les bornes d’un intervalle
- 7ExplicationInclure volontairement la borne inférieure
- 8LienChoisir les amplitudes ou les effectifs
- 9DéfiTester la règle des bornes
- 10ExempleSoustraire le minimum avant de diviser
- 11ExempleMesurer la distance à la moyenne
- 12ConseilÉcrêter sans supprimer une observation
- 13ExplicationReprésenter l’appartenance aux catégories
- 14DéfiExpliquer une ligne d’indicatrices toutes fausses
- 15RécapitulatifVérifier la représentation créée
3Transformer du texte incohérent en étiquettes utiles
17 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDonner au texte une structure cohérente
- 2ExplicationAppliquer une méthode à chaque chaîne
- 3ExempleDécouper uniquement là où le format l’exige
- 4ConseilConserver une recherche de texte littérale
- 5DéfiPréparer une clé textuelle de fusion
- 6ExplicationConstruire un motif de quantité
- 7ExempleExtraire la première quantité
- 8LienChoisir toutes les correspondances lorsqu’une seule ne suffit pas
- 9DéfiRefuser une correspondance partielle de code
- 10ConseilLimiter la portion de texte capturée par un motif
- 11ExempleDistinguer la liste des étiquettes de ses codes
- 12ExplicationDonner aux tailles l’ordre voulu
- 13ConseilPréparer l’ajout d’une nouvelle étiquette
- 14DéfiGarder les catégories vides visibles
- 15LienCombiner des catégories entre lots
- 16DéfiNettoyer avant de définir la liste autorisée
- 17RécapitulatifExaminer les valeurs textuelles et leur stockage
4Combiner des tables et rendre compte de chaque ligne
18 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionChoisir la relation entre les tables
- 2ExempleNommer explicitement la clé commune
- 3ExplicationConserver le côté nécessaire
- 4Point cléPrévoir toutes les paires correspondantes
- 5ConseilTransformer la relation en règle vérifiée
- 6ExempleCompter séparément les clés sans correspondance
- 7DéfiTrouver la cause des lignes supplémentaires
- 8ExempleFaire correspondre une colonne de gauche à un index de droite
- 9ConseilDistinguer les colonnes de même nom
- 10ExempleDonner la priorité à la source principale
- 11LienSuivre les étiquettes lors de l’addition des valeurs
- 12DéfiCompléter la bonne observation
- 13ExempleAjouter des observations en faisant correspondre les noms de colonnes
- 14ExplicationConserver une étiquette de provenance ou créer un nouvel index
- 15Point cléAligner les lignes lors de l’ajout de colonnes
- 16DéfiDiagnostiquer les nouvelles distances manquantes
- 17DéfiCombiner les lots avant d’ajouter les détails de correspondance
- 18RécapitulatifRendre compte des ajouts et des correspondances
5Remodeler les valeurs en conservant leurs étiquettes
18 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionSuivre l’identité de chaque mesure
- 2ExempleDonner deux étiquettes à une ligne
- 3ExplicationSélectionner le niveau voulu
- 4ConseilTrier après avoir modifié le rôle des niveaux
- 5DéfiSélectionner un niveau interne sans modifier les données
- 6ExempleDéplacer les colonnes d’années dans l’index
- 7ExplicationChoisir le niveau qui devient des colonnes
- 8Point cléReconnaître une valeur manquante nouvellement visible
- 9DéfiTrouver pourquoi le passage au format large échoue
- 10LienChoisir le format long ou large pour la tâche suivante
- 11ExemplePivoter une paire unique dans une cellule
- 12ExplicationAgréger uniquement lorsque c’est voulu
- 13ExempleDépivoter les mesures en conservant les identifiants
- 14ConseilVérifier le type pris par une étiquette de colonne
- 15DéfiRetrouver une cellule manquante au format large
- 16LienRétablir une table prête pour les opérations sur les colonnes
- 17DéfiChoisir le traitement des mesures répétées
- 18RécapitulatifVérifier la forme, l’unicité et la signification
Préparer les données avec pandas : QCM
Série 1 : Lire les données et prévoir des changements simples10 Questions Pratiques
Question 1 sur 10
NaN et 12. Quelle est sa moyenne par défaut ?Afficher la réponseMasquer la réponse
len compte les positions ; la moyenne par défaut ignore les valeurs manquantes.Question 2 sur 10
df.isna().any(axis=1).sum() compte-t-il ?Afficher la réponseMasquer la réponse
Question 3 sur 10
item, mass_kg et note. La ligne U a une masse connue et une note manquante ; la ligne V a une masse manquante et une note connue. Les deux noms d’articles sont connus. Que conserve df.dropna(subset=["mass_kg"]) ?Afficher la réponseMasquer la réponse
Question 4 sur 10
s.map({"A": "active", "B": "blocked"}) ?Afficher la réponseMasquer la réponse
replace avec ce dictionnaire. Un dictionnaire transmis à map définit les sorties de toute la mise en correspondance, et pas seulement des modifications de certaines valeurs.Question 5 sur 10
pd.cut(x, [0, 10, 20]) avec les paramètres par défaut. Où va 10 ?Afficher la réponseMasquer la réponse
right=False.Question 6 sur 10
s.str.strip().str.lower(), combien reste-t-il de valeurs distinctes et de lignes ?Afficher la réponseMasquer la réponse
Question 7 sur 10
str.contains(r"\d+") et str.fullmatch(r"\d+") le classent-ils ?Afficher la réponseMasquer la réponse
Question 8 sur 10
Afficher la réponseMasquer la réponse
Question 9 sur 10
id, km. Le lot B de trois lignes contient les colonnes id, km, flag. Quelle forme résulte de pd.concat([a, b], ignore_index=True) ?Afficher la réponseMasquer la réponse
join="inner" ; réinitialiser l’index ne supprime pas une colonne supplémentaire.Question 10 sur 10
station, dry et wet. Quelle longueur obtient-on en dépivotant les deux colonnes de mesures avec id_vars="station" ?Afficher la réponseMasquer la réponse
Série 2 : Choisir des méthodes pour les tâches courantes de préparation des données10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
drop_duplicates(subset="id", keep=False) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
NaN ; NaN ; 11,0. Que produit ffill(limit=1) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
pd.to_numeric(..., errors="coerce"), quelles valeurs restent ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
s.replace("Rd", "Road") ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
NaN ; la Series b contient q = 9, r = 2. Quel est le résultat de a.combine_first(b) ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
.loc["C"] pour obtenir les totaux par site pour le mois 6. Quelle correction conserve les relevés et donne les totaux nécessaires ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Suivre les étiquettes, les clés et les changements de forme10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
"", " " et None, créées directement en mémoire. Combien de valeurs s.isna().sum() compte-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
qcut ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
s.str.extract(r"(\d+)\s*kg", expand=False) suivi d’une conversion numérique ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
["small", "large"], puis les valeurs sont comptées avec dropna=False. Quels effectifs apparaissent ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
_merge pour both, left_only et right_only ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
x.add(y, fill_value=0), quelle est la somme des valeurs obtenues ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
swaplevel("city", "year").sort_index(), que sélectionne .loc[2027] ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
pivot_table, en utilisant les sites comme lignes, les années comme colonnes et l’agrégation par défaut, puis en dépivotant l’unique colonne d’année ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Diagnostiquer les changements dans une chaîne de nettoyage10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
NaN. Tu enregistres un indicateur de valeurs manquantes, puis remplaces la valeur manquante par la médiane de la colonne. Quelle valeur est utilisée et combien de valeurs de l’indicateur sont vraies ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
None, « 9 ». Après to_numeric(errors="coerce"), combien de valeurs présentes à l’origine sont devenues manquantes ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
cut avec les bornes [0, 10, 20] et les indicatrices par défaut, deux lignes ont toutes leurs indicatrices fausses. Tu dois classer les masses valides et identifier séparément les relevés inconnus. Quelle correction convient ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
s.str.split("/", n=1, expand=True) avec « zone/aisle/bin » ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
r"(\d+)" et les convertir. Quelles valeurs numériques restent ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
id, km. La table b possède une ligne avec les colonnes id, Km. Après concaténation des lignes avec le traitement des colonnes par défaut, combien de cellules sont manquantes dans les deux colonnes de distances réunies ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
.loc[2026], puis effectue un pivotement. Quelle correction sélectionne les données et produit une seule ligne de rapport ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
site, day et night. Une cellule de nuit est manquante. Après dépivotage des deux mesures, suppression des valeurs manquantes et pivotement inverse, quels sont le nombre de lignes au format long et le nombre de cellules manquantes au format large ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 5 : Raisonner sur des transformations liées10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
NaN et 6. Sa documentation définit -99 comme manquant et 0 comme un relevé réel. Après nettoyage, quels sont le nombre de valeurs connues et leur moyenne ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
{"a": "4", "b": "bad"}, puis applique une coercition numérique. Quelles entrées d’origine sont finalement manquantes et pourquoi ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
NaN ; les valeurs de secours sont a = 50, b = 7, c = 9. Après primary.combine_first(backup), que changerait l’inversion de la priorité des sources ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
kg et count, toutes deux de type nullable "Int64". Un troisième ne possède que kg avec ce type. Après concaténation des lignes, quelle proposition décrit le mieux la colonne count obtenue ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Tu bloques sur ton propre exercice ? Aide aux Devoirs
Mots-Clés
A
Accesseur str
s.str.lower() pour mettre une colonne entière de villes en minuscules en une expression.Alignement des étiquettes
Axe
C
Caractères d’espacement
str.strip().Catégorie inutilisée
Chaîne brute
r qui conserve les barres obliques inverses pour des usages comme les motifs d’expressions régulières.r"\d+", afin que sa barre oblique inverse parvienne au moteur d’expressions régulières.Classe
(0, 10], la mesure 10 est incluse et la mesure 0 est exclue.Classe de caractères
\d ou d’un intervalle comme [A-Z] dans un motif.[A-Z] correspond à une lettre majuscule dans un code d’inventaire avant ses chiffres.Clé d’enregistrement
Clé de provenance
concat devient une étiquette d’index externe qui identifie la partie d’origine de chaque ligne ou colonne.Code de catégorie
Coercition
to_numeric, la coercition convertit les valeurs lisibles en nombres et transforme les entrées illisibles en valeurs manquantes au lieu de déclencher une erreur.Colonne indicatrice
get_dummies vaut vrai uniquement pour les lignes portant l’étiquette blue.Combinaison manquante
NaN lorsque les relevés au format long sont désempilés.combine_first
combine_first pour compléter les mesures manquantes depuis une source de secours tout en conservant les valeurs connues de la source principale.Concaténation
Conversion de type
Copie à l’écriture
Correspondance complète
r"\d+" accepte « 204 » et refuse « 204x », même si les deux chaînes contiennent des chiffres.Coupe transversale
D
Découpage de chaînes
Discrétisation par quantiles
qcut pour comparer des groupes bas, intermédiaire et haut contenant des nombres de relevés similaires.dropna
dropna(subset=["mass_kg"]) lorsque les lignes utilisables doivent avoir une masse, même si un autre champ est incomplet.É
Écrêtage
E
Expression régulière
F
Format large
Format long
Fusion
G
Groupe de capture
I
id_vars
id_vars="station" évite que les noms de stations soient mélangés aux relevés numériques créés par un dépivotage.ignore_index
ignore_index=True lorsque les fichiers mensuels possèdent des numéros de lignes sans importance qui se répéteraient sinon.Imputation
Indicateur de fusion
Interpolation
NaN, 12 en 8, 10, 12 lorsqu’une estimation en ligne droite convient.J
Jointure à gauche
Jointure externe complète
Jointure interne
Jointure sur l’index
join de pandas utilise l’index de droite même lorsqu’une colonne clé de gauche est indiquée.L
Ligne en double
M
map
map de codes de pays fait apparaître les codes absents du dictionnaire sous forme de valeurs manquantes que l’analyste peut examiner.Masque des valeurs manquantes
melt
melt de quatre colonnes d’années crée quatre lignes par ville, y compris pour les cellules de mesures vides.MultiIndex
N
NaN
isna() pour trouver les NaN dans la colonne de température avant de compter les relevés disponibles pour une moyenne.NaT
isna() la détecte en même temps que les relevés numériques manquants.Niveau d’index
loc à une seule étiquette.Normalisation de la casse
Normalisation min-max
O
Opération vectorisée
P
pivot
pivot sur la station et le mois exige un relevé pour chaque cellule station/mois du résultat.pivot_table
pivot_table avec aggfunc="sum" lorsque des expéditions distinctes doivent être additionnées dans un total quotidien.Propagation de la dernière valeur connue
Propagation de la prochaine valeur connue
R
Recherche littérale
Relation plusieurs-à-un
Remodelage
rename
rename(columns={"Weight": "mass_kg"}) pour donner un sens clair à un en-tête sans modifier ses cellules.Répétition gloutonne
r"<.*>" peut couvrir les deux balises et le texte situé entre elles dans une courte chaîne balisée.replace
replace peut remplacer « pending » par « open » sans modifier les autres valeurs de statut.reset_index
reset_index(level="year") pour rétablir l’année comme colonne tout en laissant la ville dans l’index.S
Score z
stack
stack sur une table de villes avec des colonnes d’années donne des paires d’index ville/année pour les mêmes valeurs de ventes.subset
subset="order_id" pour détecter les clés de commandes répétées même lorsque leurs poids enregistrés diffèrent.Suffixe
_sensor distingue une colonne de relevés d’une colonne de même nom dans une table de secours.T
Tri de l’index
Type catégoriel
Type de données nullable
"Int64" pour des entiers avec pd.NA.U
Unicité
Union de catégories
unstack
unstack("year") pour placer chaque année dans une colonne de ventes distincte pour chaque ville.V
Valeur manquante
rain_mm signifie que le relevé est indisponible ; il faut donc la distinguer d’une absence de pluie.Variable catégorielle ordonnée
À propos de cette unité
Crée ton propre Matériel d'Étude
Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.