pandas : le tableur en Python
Le DataFrame
NumPy est parfait pour des tableaux de nombres. Mais les vraies données mélangent des dates, des textes et des nombres, avec des noms de colonnes. Pour ça, il y a pandas.
Lire un CSV entier, avec l'en-tête, la conversion des nombres et tout le reste, tient en une ligne :
import pandas as pd
df = pd.read_csv("ventes.csv")
Par convention, on appelle souvent la variable df (pour DataFrame). Pour découvrir un jeu de données, on commence toujours par les mêmes questions :
| Écriture | Ce qu'elle montre |
|---|---|
df.head() |
les 5 premières lignes (df.head(10) pour 10) |
df.shape |
la forme : (42, 5), 42 lignes et 5 colonnes |
df.columns |
les noms des colonnes |
df.dtypes |
le type de chaque colonne : int64 (entiers), float64 (décimaux), object (texte) |
df.describe() |
un résumé statistique des colonnes de nombres : moyenne, minimum, maximum... |
Rappelle-toi la fonction lire_ventes du projet : quinze lignes pour ouvrir, découper, convertir. pandas fait tout ça, et il a deviné tout seul que quantite et prix_unitaire sont des nombres.
Découvrir les ventes avec pandas
Lance (la première fois, pandas se télécharge : quelques secondes). Puis essaie df.describe() et df.tail() (les dernières lignes).
import pandas as pd
df = pd.read_csv("ventes.csv")
print(df.head())
print()
print("Forme :", df.shape)
print()
print(df.dtypes)
Colonnes : lire, calculer, créer
Une colonne se lit avec des crochets et son nom. Le résultat est une Series, qui a les mêmes méthodes de résumé que les tableaux NumPy :
df["quantite"] # la colonne quantite
df["quantite"].sum() # 170 : le total des quantités
df["prix_unitaire"].mean() # le prix moyen
Pour plusieurs colonnes, on donne une liste de noms : deux paires de crochets.
df[["produit", "vendeur"]]
Créer une colonne
Comme avec NumPy, les calculs entre colonnes se font ligne par ligne, sans boucle. Et on crée une nouvelle colonne en lui donnant un nom :
df["montant"] = df["quantite"] * df["prix_unitaire"]
La colonne montant est ajoutée à droite du tableau : c'est une colonne calculée, comme le mois du projet, en une ligne.
Compter les valeurs
| Écriture | Résultat |
|---|---|
df["produit"].unique() |
les valeurs différentes : ['riz' 'huile' 'sucre' ...] |
df["produit"].nunique() |
combien de valeurs différentes : 6 |
df["produit"].value_counts() |
combien de fois apparaît chaque valeur, de la plus fréquente à la moins fréquente |
Exercice : Le chiffre d'affaires en trois lignes
Avec pandas, calcule :
- la colonne
montantdu DataFrame (quantité x prix unitaire) ; ca: le chiffre d'affaires total ;nb_produits: le nombre de produits différents ;plus_frequent: le produit qui apparaît dans le plus de ventes (une seule valeur, un texte).
Voir une solution
import pandas as pd
df = pd.read_csv("ventes.csv")
df["montant"] = df["quantite"] * df["prix_unitaire"]
ca = df["montant"].sum()
nb_produits = df["produit"].nunique()
plus_frequent = df["produit"].value_counts().idxmax()
print(ca, nb_produits, plus_frequent)Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice
Filtrer les lignes et trier
Filtrer les lignes d'un DataFrame marche exactement comme le masque NumPy :
df["produit"] == "riz" # une Series de True et False
df[df["produit"] == "riz"] # seulement les ventes de riz
Lis la deuxième ligne de l'intérieur vers l'extérieur : on calcule le masque, puis df[masque] garde les lignes où il vaut True. Le résultat est un nouveau DataFrame.
Plusieurs conditions : &, |, et des parenthèses, comme avec NumPy.
df[(df["vendeur"] == "Paul") & (df["quantite"] >= 5)]
Trier
df.sort_values("montant", ascending=False).head(3) # les 3 plus grosses ventes
Pour transformer une colonne en liste Python ordinaire : .tolist().
Exercice : Les grosses ventes de Paul
Le DataFrame et sa colonne montant sont prêts. Calcule :
paul: le DataFrame des ventes de Paul ;grosses: le nombre de ventes de Paul d'un montant supérieur ou égal à 5 000 FCFA ;top3: la liste des 3 plus gros montants de tout le fichier, du plus grand au plus petit ;riz_sucre: le chiffre d'affaires total du riz et du sucre réunis.
Voir une solution
import pandas as pd
df = pd.read_csv("ventes.csv")
df["montant"] = df["quantite"] * df["prix_unitaire"]
paul = df[df["vendeur"] == "Paul"]
grosses = len(paul[paul["montant"] >= 5000])
top3 = df.sort_values("montant", ascending=False)["montant"].head(3).tolist()
riz_sucre = df[df["produit"].isin(["riz", "sucre"])]["montant"].sum()Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice
Teste-toi
Quelle écriture garde les ventes de riz ou de sucre faites par Awa ?
df[df["produit"] == "riz" or "sucre" and df["vendeur"] == "Awa"]df[(df["produit"].isin(["riz", "sucre"])) & (df["vendeur"] == "Awa")](bonne réponse)df[(df["produit"] == "riz") | (df["produit"] == "sucre") | (df["vendeur"] == "Awa")]df["riz", "sucre", "Awa"]