Transformer avec Python
- Leçon 11
- 50 min
- Module 4 : Nettoyer et transformer les données
Leçon 11 sur 18 · SQL et préparation des données pour l'IATransformer avec Python
1. Sources et structure des données
2. L'essentiel de SQL
3. Des requêtes d'analyse utiles
4. Nettoyer et transformer les données
5. Préparer la modélisation sans risque
6. Contrats de données et passation
Ce que vous saurez faire
Chargez l’extrait dans pandas pour que chaque colonne ait le type choisi, et non un type deviné par pandas. Puis joignez et modifiez les données par étapes qui se vérifient elles-mêmes et comptent leurs changements.
Carnet JupyterFaites cette leçon dans un carnet Jupyter
Le carnet (notebook) Jupyter contient chaque script, tâche et vérification de cette leçon, avec les instructions. Il montre le même comportement de pandas 3. Ses cellules de préparation installent pandas, créent la base de données et produisent l’extrait. Il ne nécessite donc aucune préparation locale. Lisez les explications ici et exécutez le code dans le carnet.
Le carnet est en anglais. Colab et Kaggle ouvrent votre propre copie. Il faut un compte Google ou Kaggle gratuit. Vous êtes bloqué ? Consultez le carnet de solution.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les problèmes de l’extrait et leurs nombres, présentés dans Profiler avant de modifier.
- Un fichier CSV n’a pas de types : chaque valeur est du texte. Vous l’avez vu avec
csv.DictReaderdans Lire et écrire des fichiers : CSV et JSON. - Les jointures internes et gauches, et comment une clé répétée répète les lignes, dans Joindre des tables.
Ce qu’il vous faut sur votre ordinateur (seulement pour le travail local; le carnet n’en a pas besoin)
- Le dossier
~/projects/ticket-data, avec les fichiers bruts dansdata/raw/, provenant de Préparer une base de données d’exercice : créer la base de données. S’ils manquent, exécutez de nouveaupython get_data.py. - Les extraits
data/extract/tickets.csvetdata/extract/outcomes.csv, provenant de Une extraction reproductible : exercice guidé. Si le script manque ou ne fonctionne pas, copiezscripts/extract.pyet les deux fichiers dequeries/depuis les scripts terminés du cours. Puis exécutezpython scripts/extract.py. - L’environnement
.venvavec pandas 3.0.6, provenant de Profiler avant de modifier : le même profil dans pandas. Activez-le dans un terminal ouvert dans le dossier du projet (source .venv/bin/activate; sous Windows,.venv\Scripts\Activate.ps1). L’invite commence par(.venv). Si l’environnement ne fonctionne pas, supprimez le dossier.venvet suivez de nouveau cette section. Isoler les dépendances explique pourquoi cela ne présente aucun risque. reports/profile.md, provenant de Profiler avant de modifier : exercice guidé. Cette leçon y ajoute une ligne. S’il manque, créez le fichier avec une section « Categories » (catégories).
Testé sur macOS avec Python 3.14.6 et pandas 3.0.6. pandas 3 a changé certains comportements de pandas 2. Cette leçon montre le comportement de pandas 3. Le carnet a été testé dans Jupyter.
pandas devine les types
Section intitulée « pandas devine les types »Un fichier CSV est du texte. Quand pd.read_csv le lit, pandas examine les valeurs de chaque colonne et devine un type. La plupart de ses choix sont bons. Certains sont incorrects et ne provoquent pas d’erreur. Regardez ces trois billets de soutien fictifs. Le billet T-2 n’a pas de priorité. Sa région est NA, un nouveau code pour l’Amérique du Nord :
import io
import pandas as pd
TINY = """ticket_id,priority,region,created_atT-1,1,north,2026-03-04 09:15:00T-2,,NA,2026-03-04 10:02:00T-3,3,,2026-03-05 16:40:00"""
guessed = pd.read_csv(io.StringIO(TINY))print(guessed)print(guessed.dtypes)io.StringIO(TINY) permet à read_csv de lire le texte comme un fichier. Faites d’abord une prédiction : quel type reçoit priority?
ticket_id priority region created_at0 T-1 1.0 north 2026-03-04 09:15:001 T-2 NaN NaN 2026-03-04 10:02:002 T-3 3.0 NaN 2026-03-05 16:40:00ticket_id strpriority float64region strcreated_at strdtype: objectTrois changements silencieux :
priorityest devenu un nombre décimal, de typefloat64: 1,0 et 3,0. Le type entier standard ne peut pas contenir de valeur manquante. pandas a donc choisi un type qui le peut (NaN).- La région
NAest devenue une valeur manquante. Par défaut, pandas considère certains textes comme des valeurs manquantes :NA,N/A,null,None,nanet d’autres. Le vrai codeNAest perdu. Maintenant, T-2 ressemble à T-3, qui n’a pas de région. created_atest du texte (str), pas une date. Une comparaison comme « avant le 1er février » compare des lettres, pas des moments.
Charger avec les types que vous choisissez
Section intitulée « Charger avec les types que vous choisissez »La solution consiste à indiquer le type de chaque colonne. Ajoutez ceci au même fichier :
typed = pd.read_csv( io.StringIO(TINY), dtype={"ticket_id": "string", "priority": "Int64", "region": "string"}, keep_default_na=False, na_values=[""],)typed["created_at"] = pd.to_datetime(typed["created_at"], format="%Y-%m-%d %H:%M:%S")print(typed)print(typed.dtypes) ticket_id priority region created_at0 T-1 1 north 2026-03-04 09:15:001 T-2 <NA> NA 2026-03-04 10:02:002 T-3 3 <NA> 2026-03-05 16:40:00ticket_id stringpriority Int64region stringcreated_at datetime64[us]dtype: object| Paramètre | Son effet |
|---|---|
dtype={...} |
Donne le type de chaque colonne que vous nommez. pandas ne devine pas le type de ces colonnes. |
"Int64" (I majuscule) |
Un type entier qui peut contenir une valeur manquante. Il l’affiche sous la forme <NA>. Le type int64, avec un i minuscule, ne le peut pas. |
"Float64" (F majuscule) |
La même idée pour les nombres décimaux. |
"string" |
Un type texte dont la valeur manquante est <NA>, comme pour Int64. |
keep_default_na=False |
Désactive la liste par défaut des textes représentant des valeurs manquantes. NA reste le texte NA. |
na_values=[""] |
Seule une cellule vide est une valeur manquante. Dans cet export, une cellule vide représente le NULL de SQL dans un fichier CSV. |
pd.to_datetime(..., format=...) |
Convertit le texte en date et heure, selon le format fourni. Le type est datetime64[us] (précision à la microseconde). |
L’export de Larkfield ne contient pas de région NA aujourd’hui. Vous définissez quand même ces options. Le prochain export pourrait en contenir une, et pandas se tromperait alors sans produire d’erreur.
Dates : toujours donner le format
Section intitulée « Dates : toujours donner le format »Le format indique où se trouve chaque partie d’une date. %Y représente l’année à 4 chiffres, %m le mois, %d le jour, et %H:%M:%S les heures, minutes et secondes. Pour 2026-03-05 16:40:00, le format est %Y-%m-%d %H:%M:%S.
Que se passe-t-il si le format est incorrect? Mei inverse le jour et le mois par erreur :
import pandas as pd
times = pd.Series(["2026-03-04 09:15:00", "2026-03-05 16:40:00", "2026-03-13 08:05:00"])
print(pd.to_datetime(times, format="%Y-%m-%d %H:%M:%S"))print(pd.to_datetime(times[:2], format="%Y-%d-%m %H:%M:%S"))print(pd.to_datetime(times, format="%Y-%d-%m %H:%M:%S"))0 2026-03-04 09:15:001 2026-03-05 16:40:002 2026-03-13 08:05:00dtype: datetime64[us]0 2026-04-03 09:15:001 2026-05-03 16:40:00dtype: datetime64[us]Traceback (most recent call last): ...ValueError: time data "2026-03-13 08:05:00" doesn't match format "%Y-%d-%m %H:%M:%S". You might want to try: - passing `format` if your strings have a consistent format; ...- Avec le bon format, chaque valeur est correcte.
- Avec le mauvais format et seulement les deux premières valeurs, pandas lit le 4 mars comme le 3 avril, sans erreur. Tous les jours sont inférieurs ou égaux à 12. Chaque valeur est donc une date possible.
- Avec la troisième valeur, le jour 13 ne peut pas être un mois. pandas s’arrête donc avec une erreur. Cette erreur est une bonne nouvelle : elle révèle la faute.
Sans format, pandas devine le format à partir de la première valeur. Pour les horodatages de Larkfield, son choix est correct. Pour les dates courtes comme 04/03/2026, ce n’est pas sûr. pandas 3.0.6 lit 04/03/2026 comme le 3 avril, avec le mois en premier. Au Royaume-Uni, le même texte signifie le 4 mars. Seule la source des données peut vous dire quelle interprétation est correcte. Écrivez cette réponse dans le code sous forme de format.
Exemple détaillé : Mei charge l’extrait
Section intitulée « Exemple détaillé : Mei charge l’extrait »Mei commence scripts/clean.py. La leçon 3 y ajoutera les étapes de nettoyage. Aujourd’hui, il charge l’extrait avec un type pour chaque colonne :
"""Clean the extracted tickets and outcomes. Every input row ends in exactlyone place: the clean table, the quarantine table, or the count of removedexact duplicates. The original values stay next to the corrected ones."""
import jsonfrom pathlib import Path
import pandas as pd
IN = Path("data/extract")OUT = Path("data/clean")REPORTS = Path("reports")
TICKET_TYPES = { "ticket_id": "string", "customer_id": "string", "channel": "string", "team": "string", "priority": "Int64", "order_value": "Float64", "word_count": "Int64", "first_reply_minutes": "Int64", "priority_now": "Int64", "segment": "string", "region": "string",}TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
def load_tickets(): df = pd.read_csv(IN / "tickets.csv", dtype=TICKET_TYPES, keep_default_na=False, na_values=[""]) df["created_at"] = pd.to_datetime(df["created_at"], format=TIME_FORMAT) df["closed_at"] = pd.to_datetime(df["closed_at"], format=TIME_FORMAT) df["joined_on"] = pd.to_datetime(df["joined_on"], format="%Y-%m-%d") return df
def main(): tickets = load_tickets() print(f"Loaded {len(tickets)} ticket rows") print(tickets.dtypes) print("created_at:", tickets["created_at"].min(), "to", tickets["created_at"].max()) print("missing closed_at (open tickets):", tickets["closed_at"].isna().sum())
if __name__ == "__main__": main()json, OUT et REPORTS ne servent pas encore. La leçon 3 les utilise. main() est une vérification temporaire : la leçon 3 la remplace.
python scripts/clean.pyLoaded 1416 ticket rowsticket_id stringcustomer_id stringcreated_at datetime64[us]channel stringteam stringpriority Int64order_value Float64word_count Int64first_reply_minutes Int64priority_now Int64closed_at datetime64[us]segment stringregion stringjoined_on datetime64[us]dtype: objectcreated_at: 2026-01-05 07:30:24 to 2026-06-30 20:04:36missing closed_at (open tickets): 12Mei vérifie trois points par rapport au profil. Il y a 1 416 lignes, comme dans l’extrait. La plage de created_at reste dans la sélection de l’extrait, du 1er janvier au 30 juin. Et 12 valeurs de closed_at manquent : les mêmes 12 billets ouverts. Donc, pd.to_datetime n’a créé aucune nouvelle valeur manquante.
Joindre des tables dans pandas, avec une règle sur les clés
Section intitulée « Joindre des tables dans pandas, avec une règle sur les clés »En SQL, une jointure combine les lignes de deux tables à l’aide d’une clé. Dans pandas, la méthode est merge. L’extrait a déjà joint tickets à customers en SQL. Mei refait cette jointure dans pandas à partir des fichiers bruts. Elle veut examiner deux paramètres que SQL n’offre pas :
"""Repeat the extract's customer join in pandas, and count every row."""
import pandas as pd
READ = {"keep_default_na": False, "na_values": [""]}tickets = pd.read_csv("data/raw/tickets.csv", dtype={"customer_id": "string"}, **READ)customers = pd.read_csv("data/raw/customers.csv", dtype="string", **READ)print(f"tickets: {len(tickets)} rows, customers: {len(customers)} rows")
joined = tickets.merge( customers, on="customer_id", how="left", validate="many_to_one", indicator=True,)print(f"joined: {len(joined)} rows")print(joined["_merge"].value_counts())
no_match = joined[joined["_merge"] == "left_only"]print(f"no customer_id: {no_match['customer_id'].isna().sum()}")print(f"customer_id not in customers: {no_match['customer_id'].notna().sum()}")**READ transmet les deux paramètres du dictionnaire READ aux deux appels de read_csv. Ils ne peuvent donc pas différer. Faites d’abord une prédiction : combien de lignes une jointure gauche renvoie-t-elle?
tickets: 1417 rows, customers: 240 rowsjoined: 1417 rows_mergeboth 1396left_only 21right_only 0Name: count, dtype: int64no customer_id: 12customer_id not in customers: 9| Paramètre | Son effet |
|---|---|
how="left" |
Garde chaque ligne de la table de gauche (tickets), comme le fait LEFT JOIN. |
validate="many_to_one" |
Une règle : plusieurs billets peuvent avoir le même client. Mais chaque customer_id doit apparaître une seule fois dans customers. Sinon, merge s’arrête avec une erreur avant que les lignes se multiplient. |
indicator=True |
Ajoute la colonne _merge : both (correspondance), left_only (aucune correspondance) ou right_only (à droite seulement). |
Les nombres concordent avec ceux du module 2. Le résultat contient 1 417 lignes, comme la table de gauche. Il y a 1 396 lignes correspondantes, le nombre obtenu par la jointure interne. 21 billets n’ont aucune ligne client : 12 invités et 9 clients supprimés.
La règle sur les clés est l’élément important. Mei joint maintenant les événements de résultat aux billets de l’extrait pour ajouter team à chaque événement. Chaque événement appartient à un seul billet. La règle est donc many_to_one :
>>> import pandas as pd>>> tickets = pd.read_csv("data/extract/tickets.csv", dtype="string", keep_default_na=False, na_values=[""])>>> events = pd.read_csv("data/extract/outcomes.csv", dtype="string", keep_default_na=False, na_values=[""])>>> len(events)1869>>> len(events.merge(tickets[["ticket_id", "team"]], on="ticket_id", how="left"))1892>>> events.merge(tickets[["ticket_id", "team"]], on="ticket_id", how="left", validate="many_to_one")Traceback (most recent call last): ...pandas.errors.MergeError: Merge keys are not unique in right dataset; not a many-to-one merge
Duplicates in right: ticket_id T-10031 T-10156 T-10260 T-10337 T-10347 ...Sans validate, la jointure renvoie 1 892 lignes à partir de 1 869 événements. 23 événements apparaissent maintenant deux fois, car leur billet apparaît deux fois dans l’extrait. Rien n’échoue. Avec validate, pandas s’arrête et nomme les clés dupliquées. Ce sont les 14 doublons exacts du profil. Après drop_duplicates(), la règle est respectée. Vous l’essayez dans la variante ci-dessous.
Modifier les valeurs par étapes nommées
Section intitulée « Modifier les valeurs par étapes nommées »Une transformation est un changement aux valeurs d’une colonne. Mei suit quatre règles pour chacune :
- Une étape nommée par problème, avec un commentaire qui explique pourquoi.
- Garder l’original dans une colonne voisine, par exemple
channel_raw. - Compter les lignes que l’étape modifie.
- Modifier les lignes avec
.loc, en une seule instruction.
Voici la correction des graphies des canaux, tirée du profil. Mei l’essaie dans un petit script avant de l’ajouter à clean.py :
import pandas as pd
from clean import load_tickets
tickets = load_tickets().drop_duplicates()print(f"rows: {len(tickets)}")
channel = tickets["channel"].str.strip().str.lower().replace({"webform": "web_form"})changed = channel != tickets["channel"]print(changed.value_counts(dropna=False))print(f"respelled: {changed.fillna(False).sum()}")
tickets["channel_raw"] = tickets["channel"]tickets["channel"] = channelprint(tickets.loc[changed.fillna(False), ["ticket_id", "channel_raw", "channel"]].drop_duplicates("channel_raw"))print(tickets["channel"].value_counts(dropna=False)).str.strip() enlève les espaces au début et à la fin. .str.lower() met toutes les lettres en minuscules. .replace(...) remplace le seul mot incorrect.
rows: 1402channelFalse 1325True 39<NA> 38Name: count, dtype: Int64respelled: 39 ticket_id channel_raw channel2 T-10003 Email email12 T-10013 webform web_form111 T-10111 EMAIL email124 T-10124 chat chatchannelemail 564chat 415web_form 203phone 182<NA> 38Name: count, dtype: Int64- 1 402 lignes : les 14 doublons exacts ont été retirés.
- 39 lignes modifiées. Dans le profil, 40 lignes avaient d’autres graphies. Une ligne
EMAILétait un doublon. Il en reste donc 39. - Dans la ligne
T-10124,channel_rawvautchat, avec un espace au début. Le tableau ne montre pas l’espace, mais la comparaison le détecte. - 38 lignes valent
<NA>: un canal manquant reste manquant. L’étape n’invente pas de valeur. La leçon 3 décide quoi en faire.
Modifier les lignes avec .loc, pas en deux étapes
Section intitulée « Modifier les lignes avec .loc, pas en deux étapes »pandas 3 utilise la copie à l’écriture (copy-on-write). Quand vous sélectionnez des lignes, vous obtenez une nouvelle table qui se comporte comme une copie. Modifier la copie ne modifie jamais la table d’origine. C’est important pour une forme de code courante :
import pandas as pd
df = pd.DataFrame({ "ticket_id": ["T-1", "T-2", "T-3"], "team": ["account", "delivery", "returns"], "order_value": [None, 40.0, -1.0],})
df[df["order_value"] == -1]["order_value"] = Noneprint(df)
df.loc[df["order_value"] == -1, "order_value"] = Noneprint(df).../cow.py:9: ChainedAssignmentError: A value is being set on a copy of a DataFrame or Series through chained assignment.Such chained assignment never works to update the original DataFrame or Series, because the intermediate object on which we are setting values always behaves as a copy (due to Copy-on-Write).
Try using '.loc[row_indexer, col_indexer] = value' instead, to perform the assignment in a single step.... ticket_id team order_value0 T-1 account NaN1 T-2 delivery 40.02 T-3 returns -1.0 ticket_id team order_value0 T-1 account NaN1 T-2 delivery 40.02 T-3 returns NaNLa première ligne sélectionne les lignes, puis définit une colonne dans cette sélection. Ce sont deux étapes : une affectation chaînée. Dans pandas 3, elle ne modifie jamais df. T-3 contient encore -1.0. pandas affiche un avertissement, mais le programme continue. La forme .loc[rows, column] = value fait le changement en une étape, directement dans df. (Dans pandas 2, la première forme fonctionnait parfois, avec un autre avertissement. Le code d’anciens tutoriels peut ne rien faire dans pandas 3.)
Exercice guidé : commencer clean.py
Section intitulée « Exercice guidé : commencer clean.py »-
Créez
scripts/clean.pyavec le code de l’exemple détaillé. -
Exécutez
python scripts/clean.py. Vérifiez la sortie :Loaded 1416 ticket rows(1 416 lignes de billets chargées), etcreated_atde2026-01-05 07:30:24à2026-06-30 20:04:36. -
Créez
scripts/try_channel.pyet exécutezpython scripts/try_channel.py. Vérifiez :respelled: 39(39 graphies corrigées). -
Créez
scripts/try_str.pyavec le code ci-dessous. Il corrige les mêmes graphies, mais charge le fichier sansdtype. Prédisez d’abord le nombre.scripts/try_str.py import pandas as pdplain = pd.read_csv("data/extract/tickets.csv").drop_duplicates()print(plain["channel"].dtype)respelled = plain["channel"].str.strip().str.lower().replace({"webform": "web_form"})print("changed:", (respelled != plain["channel"]).sum()) -
Exécutez
python scripts/try_str.py. -
Ajoutez votre résultat à
reports/profile.mdsous « Categories » : 39 lignes aux graphies corrigées après le retrait des doublons.
Ce que montre l’étape 5
strchanged: 7777 = 39 lignes aux graphies corrigées + 38 canaux manquants. Avec le type str deviné, une valeur manquante est NaN, et NaN != NaN vaut True. Chaque canal manquant compte donc comme « modifié ». Avec "string", la comparaison donne <NA> pour ces lignes. fillna(False) rend la décision visible dans le code. Les deux scripts s’exécutent sans erreur. Seul le nombre montre la différence.
À vous de jouer : charger et joindre les événements de résultat
Section intitulée « À vous de jouer : charger et joindre les événements de résultat »Chargez data/extract/outcomes.csv avec des types : csat en Int64, les autres colonnes en "string", et recorded_at en date avec TIME_FORMAT. Puis joignez les événements aux billets sans doublons avec validate="many_to_one" et indicator=True. Prédisez d’abord le nombre de lignes et les nombres de _merge.
Afficher un exemple de réponse
import pandas as pd
from clean import IN, TIME_FORMAT, load_tickets
events = pd.read_csv( IN / "outcomes.csv", dtype={"outcome_id": "string", "ticket_id": "string", "status": "string", "resolution_code": "string", "csat": "Int64"}, keep_default_na=False, na_values=[""],)events["recorded_at"] = pd.to_datetime(events["recorded_at"], format=TIME_FORMAT)print(events.dtypes)
tickets = load_tickets().drop_duplicates()print(f"events: {len(events)}, tickets: {len(tickets)}")joined = events.merge( tickets[["ticket_id", "team"]], on="ticket_id", how="left", validate="many_to_one", indicator=True,)print(f"joined: {len(joined)}")print(joined["_merge"].value_counts())outcome_id stringticket_id stringrecorded_at datetime64[us]status stringresolution_code stringcsat Int64dtype: objectevents: 1869, tickets: 1402joined: 1869_mergeboth 1869left_only 0right_only 0Name: count, dtype: int64La règle est respectée après drop_duplicates() : 1 869 événements en entrée, 1 869 lignes en sortie. Chaque événement a trouvé son billet. L’extrait a exclu les 4 événements orphelins en SQL. left_only vaut donc 0.
Erreur courante
Les dates semblent correctes dans un échantillon, mais sont incorrectes
Symptôme : Mei teste un format de date sur les 50 premières lignes de l’extrait. Il n’y a aucune erreur. Plus tard, un graphique montre des billets de mai à octobre, mais l’export se termine en juin :
>>> import pandas as pd>>> sample = pd.read_csv("data/extract/tickets.csv", nrows=50)>>> created = pd.to_datetime(sample["created_at"], format="%Y-%d-%m %H:%M:%S")>>> sample["created_at"].iloc[0], created.iloc[0]('2026-01-05 07:30:24', Timestamp('2026-05-01 07:30:24'))>>> created.min(), created.max()(Timestamp('2026-05-01 07:30:24'), Timestamp('2026-10-01 15:36:08'))Cause : le format place le jour et le mois aux mauvais endroits. Les 50 premiers billets datent du 5 au 12 janvier. Tous les jours sont donc inférieurs ou égaux à 12, et chaque valeur est une date possible. Sur le fichier complet, pandas s’arrête à 2026-01-13 09:57:09 avec doesn't match format (ne correspond pas au format).
Solution :
- Écrivez le format à partir des données, partie par partie :
2026-01-05suit l’ordre année, mois, jour, donc%Y-%m-%d. - Analysez la colonne complète, pas un échantillon.
- Après l’analyse, vérifiez les dates minimale et maximale par rapport au profil. L’extrait va du 5 janvier 2026 au 30 juin 2026.
Dans le travail en IA : la date détermine quelles lignes servent à l’entraînement et lesquelles servent aux tests (module 5). Des dates incorrectes placent des billets de janvier en octobre. Le modèle s’entraîne donc sur des lignes qui semblent venir du futur.
Vérifiez votre compréhension
Vous lisez un fichier CSV sans dtype. La colonne priority contient une cellule vide. Quel type pandas lui donne-t-il, et à quoi ressemblent les valeurs?
Afficher la réponse
float64 : les valeurs ressemblent à 1.0 et 3.0, et la cellule vide est NaN. Le type entier standard ne peut pas contenir de valeur manquante. pandas change donc le type. Avec dtype={"priority": "Int64"}, les valeurs restent 1 et 3, et la cellule vide est <NA>.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Une jointure de 1 869 événements aux billets renvoie 1 892 lignes. Que fait validate="many_to_one" dans ce cas, et pourquoi est-ce mieux?
Afficher la réponse
Il arrête la jointure avec une MergeError. Elle nomme les valeurs de ticket_id qui apparaissent plusieurs fois dans la table des billets. Sans ce paramètre, 23 événements sont comptés deux fois. Tous les nombres et moyennes calculés après la jointure sont incorrects, sans erreur. La règle rend visible l’erreur silencieuse.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Dans pandas 3, que modifie df[df.team == "account"]["order_value"] = 0 dans df?
Afficher la réponse
Rien. C’est une affectation chaînée. La première sélection donne une table qui se comporte comme une copie (copie à l’écriture). L’affectation ne modifie que cette copie. pandas affiche un avertissement ChainedAssignmentError. Utilisez df.loc[df.team == "account", "order_value"] = 0.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Donnez un type à chaque colonne avec
dtype=. UtilisezInt64,Float64et"string"quand des valeurs peuvent manquer. keep_default_na=False, na_values=[""]: seule une cellule vide est une valeur manquante. Une vraie valeur commeNAest donc conservée.- Analysez les dates avec un
formatexplicite, puis vérifiez les dates minimale et maximale. Un mauvais format peut donner des dates valides, mais incorrectes. merge(..., validate="many_to_one", indicator=True)vérifie la règle sur les clés et montre quelles lignes correspondent. Comptez les lignes avant et après.- Une transformation est une étape nommée qui garde la colonne d’origine et compte ses changements. Dans pandas 3, modifiez les lignes avec
.locen une seule instruction.
Ensuite, vous décidez quoi faire de chaque problème du profil : supprimer, corriger ou garder comme valeur manquante. Vous rendez compte de chaque ligne.
Leçon suivante : Traiter les valeurs désordonnées