Lire un CSV et vérifier ce qui a été chargé
Lire un fichier avec read_csv et l'inspecter immédiatement avec shape, head, info et describe — car un fichier mal lu produit des résultats erronés sans jamais lever d'erreur.
Comment voulez-vous apprendre ?
Le problème que nous résolvons
Jusqu'ici, chaque valeur de la table a été saisie à la main dans le code. Pour trois lignes, cela fonctionne.
Les données réelles ne vivent pas dans le code. Elles vivent dans un fichier — envoyé par e-mail, exporté depuis un système ou enregistré depuis un tableur. Et le fichier comporte douze mille lignes, pas douze.
Ce fichier ressemble généralement à ceci : du texte brut, les noms de colonnes sur la première ligne, puis une ligne par enregistrement, les valeurs séparées par des virgules :
product,quantity,price
pen,12,15.0
notebook,5,60.0Il s'agit d'un CSV — comma-separated values. Le transformer en une table prend une seule ligne de code avec pandas, et c'est la ligne la plus utilisée dans pandas.
Mais il y a une habitude à prendre immédiatement après cette ligne, et c'est le véritable sujet de ce chapitre : une fois le fichier lu, regardez-le. Combien de lignes sont arrivées, si les noms de colonnes correspondent à ce que vous attendiez, si les colonnes numériques sont bien arrivées sous forme de nombres. Sautez ces trente secondes, et l'erreur refera surface bien plus tard, lorsqu'un résultat sera faux sans que rien n'ait déclenché d'erreur.
À la fin de ce chapitre, vous saurez
- Lire un fichier avec
pd.read_csv()et gérer le problème de chemin qui s'ensuit - Vérifier rapidement un fichier avec
head(),tail(),shapeetcolumns - Lire
info()pour voir d'un coup le nombre de lignes, les cellules vides et le type de chaque colonne - Résumer les colonnes numériques avec
describe() - Reconnaître et corriger une
FileNotFoundErrorainsi qu'un mauvais séparateur
Prérequis : Series et DataFrame — les deux objets de pandas.
Créer d'abord le fichier
Dans votre dossier de projet, créez un fichier nommé sales.csv avec exactement ces six lignes :
product,quantity,price
pen,12,15.0
notebook,5,60.0
bag,2,850.0
bottle,7,120.0
eraser,30,8.0La première ligne ne contient pas de données, ce sont les noms de colonnes — l'en-tête. Les cinq autres lignes sont cinq lignes de données.
Le lire, en une seule ligne
import pandas as pd
sales = pd.read_csv("sales.csv")
print(sales)product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0
3 bottle 7 120.0
4 eraser 30 8.0Cette unique ligne a fait trois choses, et toutes les trois en silence :
Tout d'abord, elle a considéré la première ligne comme l'en-tête — ainsi, product, quantity et price sont devenus des noms de colonnes plutôt qu'une ligne de données.
Ensuite, elle a construit un index, les chiffres 0 à 4 sur la gauche. Cela ne figurait pas dans le fichier.
Enfin, et c'est là le point essentiel, elle a deviné le type de chaque colonne. Tout dans le fichier est du texte — 12, ce sont en réalité deux caractères. Pandas a examiné chaque colonne et a déterminé s'il s'agissait de nombres ou de texte.
Cette déduction est généralement correcte. Mais lorsqu'elle se trompe, aucune erreur n'apparaît — et c'est exactement la raison pour laquelle vous devez vérifier.
Les quatre points à vérifier après la lecture d'un fichier
shape — le volume de données chargé
print(sales.shape)(5, 3)Cinq lignes, trois colonnes. Le fichier comportait six lignes et la table en compte cinq, car l'en-tête n'est pas une ligne de données. Si ce nombre est bien inférieur à ce que vous attendiez, ou s'il comporte exactement une ligne de trop, c'est le premier signe que quelque chose a été mal lu.
head() et tail() — le début et la fin
print(sales.head(3))product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0Afficher l'intégralité des douze mille lignes d'un vrai fichier sature le terminal et ne vous apprend rien. head() montre les premières lignes — cinq si vous ne précisez rien. tail() fait de même pour la fin, et regarder la fin est particulièrement utile, car les fichiers exportés comportent souvent une ligne vide parasite ou une ligne de totaux tout en bas.
info() — tout d'un seul coup d'œil
sales.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 product 5 non-null object
1 quantity 5 non-null int64
2 price 5 non-null float64
dtypes: float64(1), int64(1), object(1)
memory usage: 252.0+ bytesRemarquez que nous écrivons sales.info() et non print(sales.info()) — cette méthode affiche son contenu d'elle-même et ne renvoie rien, donc l'envelopper dans print ajoute un None parasite à la fin.
C'est la commande la plus utile à exécuter après avoir lu un fichier, car elle rassemble deux informations essentielles :
Non-Null Count — le nombre de cellules réellement remplies dans chaque colonne. Les trois indiquent ici 5 non-null, rien n'est donc vide. Un 4 non-null quelque part signifie qu'une cellule de cette colonne est vide, ce qui faussera vos calculs.
Dtype — ce que la déduction a retenu. quantity est arrivée sous forme de int64, price de float64, et product de object. C'est exactement ce que nous voulions.
(Le chiffre de memory usage sur la dernière ligne peut être différent sur votre machine, et cela n'a pas d'importance.)
describe() — un résumé des colonnes numériques
print(sales.describe())quantity price
count 5.00000 5.000000
mean 11.20000 210.600000
std 11.12205 360.217712
min 2.00000 8.000000
25% 5.00000 15.000000
50% 7.00000 60.000000
75% 12.00000 120.000000
max 30.00000 850.000000Cette méthode sélectionne les colonnes numériques et applique huit calculs sur chacune d'elles. product est absente, car il s'agit de texte.
Un détail ici devrait attirer votre attention : la moyenne (mean) de price est de 210.6, alors que le 50% — la médiane — n'est que de 60. Un écart aussi grand signifie qu'une valeur se situe bien au-dessus des autres, et max la désigne clairement : 850. C'est ainsi que l'on lit describe() — quand la moyenne et la médiane s'éloignent l'une de l'autre, c'est là qu'il faut regarder.
Un exemple complet
report.py :
import pandas as pd
sales = pd.read_csv("sales.csv")
print("Rows, columns:", sales.shape)
print()
print(sales.head(3))
print()
print("Columns :", list(sales.columns))
print("Total qty :", sales["quantity"].sum())
print("Avg price :", round(sales["price"].mean(), 2))Rows, columns: (5, 3)
product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0
Columns : ['product', 'quantity', 'price']
Total qty : 56
Avg price : 210.6C'est un petit programme, mais sa structure mérite qu'on s'y attarde — lire, puis vérifier, puis calculer. shape et head() ne sont pas des calculs, ce sont des questions : ai-je lu le bon fichier ? Y a-t-il autant de lignes qu'il devrait y en avoir ?
Et il y a une bonne raison d'afficher list(sales.columns). Sous forme de liste, chaque nom apparaît entre guillemets, ce qui rend immédiatement visible un nom comme 'quantity ' comportant un espace final. Affiché autrement, cet espace reste invisible et ressurgit plus tard sous la forme d'une KeyError.
Quand ça casse
FileNotFoundError: [Errno 2] No such file or directory: 'sales.csv' Python cherche dans le dossier actuel et ne l'y a pas trouvé. C'est le même problème qu'au chapitre deux du cours Python : le terminal se trouve à un endroit et le fichier à un autre. Exécutez pwd pour voir où vous êtes, dir pour voir si le fichier est là, puis cd. Sous Windows, le vrai nom est parfois sales.csv.txt — activez l'affichage des extensions de noms de fichiers dans l'Explorateur.
Le fichier entier est arrivé sous forme d'une seule colonne Le séparateur n'est pas une virgule. Les fichiers enregistrés dans une grande partie de l'Europe utilisent un point-virgule, car la virgule y sert de séparateur décimal. Écrivez pd.read_csv("sales.csv", sep=";"). Pour les fichiers séparés par des tabulations, utilisez sep="\t".
Une colonne numérique est arrivée avec le type object Du texte s'est glissé dans la colonne — un N/A, un -, une cellule vide ou un séparateur de milliers (1,200). Exécutez df["col"].unique() pour voir ce qui s'y trouve réellement ; la valeur anormale saute généralement aux yeux. La solution est pd.to_numeric(df["col"], errors="coerce"), qui convertit tout élément non numérique en cellule vide — ce que nous aborderons en détail dans le chapitre sur les données manquantes.
UnicodeDecodeError Le fichier n'est pas enregistré en UTF-8, ce qui arrive constamment avec les fichiers issus d'un tableur. Essayez pd.read_csv("sales.csv", encoding="utf-8-sig"), ou à défaut encoding="latin-1".
La première ligne de données est devenue le nom des colonnes, alors que le fichier n'avait pas d'en-tête Écrivez pd.read_csv("sales.csv", header=None) et les colonnes deviennent 0, 1, 2. Pour les nommer, ajoutez names=["product", "quantity", "price"].
Un None parasite s'affiche après sales.info() Le code a été écrit sous la forme print(sales.info()). info() affiche son résultat d'elle-même et ne renvoie rien, donc print affiche le None renvoyé. Écrivez simplement sales.info().
Étape 4 sur 6 — Prédire
Vérifiez votre compréhension
Le fichier comporte six lignes. Qu'indique shape ?
from io import StringIO
import pandas as pd
# Stands in for sales.csv, so this snippet runs on its own.
RAW = """product,quantity,price
pen,12,15.0
notebook,5,60.0
bag,2,850.0
bottle,7,120.0
eraser,30,8.0
"""
sales = pd.read_csv(StringIO(RAW))
print(sales.shape)- A(5, 3)
- B(5, 4)
- C(3, 5)
- D(6, 3)
Que vous indique la colonne Non-Null Count de info() ?
- ACombien de cellules de chaque colonne sont réellement remplies — un nombre inférieur au nombre de lignes signifie qu'il y a des cellules vides
- BCombien de cellules de chaque colonne sont vides
- CCombien d'espace mémoire occupe chaque colonne
- DCombien de valeurs distinctes contient chaque colonne
Le fichier est séparé par des points-virgules, mais aucun sep n'a été fourni. Qu'est-ce qui est affiché ?
from io import StringIO
import pandas as pd
# Stands in for sales.csv, so this snippet runs on its own.
RAW = """product;quantity
pen;12
notebook;5
"""
df = pd.read_csv(StringIO(RAW))
print(df.shape)
print(list(df.columns))- A(3, 1) ['product;quantity']
- B(2, 1) ['product;quantity']
- C(2, 2) ['product', 'quantity']
- DUne `ParserError`
Répondre nécessite un compte
Connectez-vous pour vérifier vos réponses
Les questions sont ci-dessus, et les résoudre de tête est ce qui compte vraiment. Connectez-vous pour voir les réponses, les explications et les indices à trois niveaux.
À vous de jouer
Créez un fichier nommé students.csv contenant au moins huit personnes, réparties en trois colonnes — un nom, un âge et une note.
Écrivez ensuite report.py, qui :
- Lit le fichier
- Affiche
shapeetlist(columns) - Affiche
head(3)ettail(2) - Exécute
info()et indique si les types des trois colonnes correspondent à ce que vous attendiez - Affiche
describe(), puis séparément la moyenne et le maximum de la colonne des notes
Provoquez ensuite des erreurs volontairement — à trois reprises, en observant ce qui se passe à chaque fois :
- Mettez
N/Adans une cellule de la colonne des notes. Qu'indique à présentDtypedansinfo()? Qu'est-il arrivé à la moyenne ? - Remplacez chaque virgule du fichier par un point-virgule. Qu'indique à présent
shape, et pourquoi ? - Supprimez la première ligne, l'en-tête. Combien de lignes sont arrivées, et quels sont les noms des colonnes à présent ?
Ces trois situations se produisent constamment dans le travail quotidien, et chacune d'elles a un symptôme bien distinct. Les provoquer délibérément aujourd'hui vous permettra de les reconnaître au premier coup d'œil la prochaine fois.
Étape 6 sur 6
Défi — le quiz du chapitre
Dix questions, de la plus facile à la plus difficile. Les dernières sont difficiles exprès.
Connectez-vous pour faire le quiz