ParcoursOuvrir l'appli

pandas : le tableur en Python

Données : NumPy et pandas · 55 min

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 montant du 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 ?
  1. df[df["produit"] == "riz" or "sucre" and df["vendeur"] == "Awa"]
  2. df[(df["produit"].isin(["riz", "sucre"])) & (df["vendeur"] == "Awa")] (bonne réponse)
  3. df[(df["produit"] == "riz") | (df["produit"] == "sucre") | (df["vendeur"] == "Awa")]
  4. df["riz", "sucre", "Awa"]