GUIDE COMPLET
Certification Python 3 — Journee 4
Pandas applique : Projets complets, NumPy, Concatenation, Analyse des ventes
Ce document couvre la Journee 4 : deux projets complets (Automobiles + Ventes),
operations pandas avancees, NumPy, et toutes les astuces d'analyse de donnees.
1. NUMPY — TABLEAUX NUMERIQUES
1.1 Creer des tableaux NumPy
NumPy fournit des tableaux multidimensionnels (ndarray) optimises pour le calcul numerique.
import numpy as np
# Tableaux 1D
a = [Link]([1, 2, 3, 4])
b = [Link]([10, 20, 30, 40])
# Tableau 2D (matrice) : tableau de tableaux
m = [Link]([a, b])
# m = [[1, 2, 3, 4],
# [10, 20, 30, 40]]
# Autres creations
[Link]((3, 4)) # matrice 3x4 de zeros
[Link]((2, 3)) # matrice 2x3 de uns
[Link](0, 1000, 100) # 100 entiers aleatoires entre 0 et 999
[Link](0, 15, 10) # 10 valeurs egalement espacees entre 0 et 15
[Link](0, 10, 2) # [0, 2, 4, 6, 8]
1.2 Parcourir un tableau NumPy
a = [Link]([1, 2, 3, 4])
b = [Link]([10, 20, 30, 40])
m = [Link]([a, b])
# Parcourir une matrice 2D
for ligne in m:
print(ligne) # affiche chaque ligne : [1,2,3,4] puis [10,20,30,40]
for element in ligne:
print(element) # affiche chaque element : 1, 2, 3... 10, 20...
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 1
# Proprietes du tableau
[Link] # (2, 4) : 2 lignes, 4 colonnes
[Link] # 2 : nombre de dimensions
[Link] # int64 : type des elements
len(m) # 2 : nombre de lignes
1.3 Operations NumPy
# Operations vectorisees (appliquees a chaque element)
a = [Link]([1, 2, 3, 4])
a + 10 # [11, 12, 13, 14]
a * 2 # [2, 4, 6, 8]
a ** 2 # [1, 4, 9, 16]
# Operations entre tableaux
b = [Link]([10, 20, 30, 40])
a + b # [11, 22, 33, 44]
# Fonctions statistiques
[Link](a) # moyenne
[Link](a) # somme
[Link](a) # maximum
[Link](a) # minimum
[Link](a) # ecart-type
[Link](a) # moyenne ponderee (comme mean si sans poids)
DIFFERENCE NumPy vs liste Python :
[Link]([1,2,3]) * 2 => [2, 4, 6] (operation vectorisee)
[1,2,3] * 2 => [1,2,3,1,2,3] (repetition de la liste !)
NumPy est BEAUCOUP plus rapide pour les calculs sur grandes donnees.
2. CONCATENATION ET FUSION DE DATAFRAMES
2.1 [Link]() — Empiler des DataFrames
Concatener = assembler plusieurs DataFrames en un seul (empilement vertical ou horizontal).
import pandas as pd
# Concatenation verticale (empilement de lignes)
df_total = [Link]([df1, df2, df3])
# Avec cles pour identifier l'origine
df_total = [Link]([df1, df2], keys=['Allemagne', 'Japon'])
# Reinitialiser l'index apres concatenation
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 2
df_total = [Link]([df1, df2]).reset_index(drop=True)
# Concatenation horizontale (cote a cote, axis=1)
df_total = [Link]([df1, df2], axis=1)
2.2 Fusionner tous les CSV d'un dossier — PATTERN PROJET
Pattern tres frequent en exam : lire tous les fichiers d'un dossier et les concatener.
import os
import pandas as pd
path = './Data' # chemin du dossier
Global = [Link]() # DataFrame vide accumulateur
# Lister tous les fichiers CSV du dossier
files = [f for f in [Link](path) if [Link]('.csv')]
# Lire et concatener chaque fichier
for fichier in files:
print('Traitement :', fichier)
df_local = pd.read_csv(path + '/' + fichier)
Global = [Link]([Global, df_local])
# Sauvegarder le resultat
Global.to_csv('all_data.csv', index=False)
print([Link]) # verifier le nombre de lignes/colonnes
ASTUCE : [Link]() sans reset_index() => index dupliques !
Apres concatenation, toujours faire .reset_index(drop=True) si l'index doit etre unique.
ASTUCE : index=False dans to_csv() => ne pas sauvegarder l'index comme colonne.
2.3 [Link].from_dict() — Depuis un dictionnaire
# Creer un DataFrame depuis un dictionnaire Python
GermanCars = {
'Company': ['Ford', 'Mercedes', 'BMW', 'Audi'],
'Price': [23845, 171995, 135925, 71400]
}
carsDf1 = [Link].from_dict(GermanCars)
japaneseCars = {
'Company': ['Toyota', 'Honda', 'Nissan', 'Mitsubishi'],
'Price': [29995, 23600, 61500, 58900]
}
carsDf2 = [Link].from_dict(japaneseCars)
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 3
# Concatener avec cles hierarchiques
carsDf = [Link]([carsDf1, carsDf2], keys=['Germany', 'Japan'])
print(carsDf)
# Resultat : index hierarchique (Germany/Japan) + index numerique
3. PROJET 1 — ANALYSE DES AUTOMOBILES
3.1 Vue d'ensemble du projet
Fichier source : [Link]. Colonnes cibles : index, company, body-style, wheel-base, length,
engine-type, num-of-cylinders, horsepower, average-mileage, price.
3.2 Code complet — Solution
import pandas as pd
# Q1 : Charger et explorer les donnees
df = pd.read_csv('./Data/[Link]')
autos = df[['index','company','body-style','wheel-base','length',
'engine-type','num-of-cylinders','horsepower',
'average-mileage','price']]
print([Link](5)) # 5 premieres lignes
print([Link]) # types des colonnes
# Q2 : Nettoyage des donnees
[Link](inplace=True) # supprimer les NaN
[Link](0) # remplacer les 0 restants
autos.to_csv('./Data/[Link]') # sauvegarder
# Q3 : La voiture la plus chere (company, horsepower, price)
plus_chere = autos[['company','horsepower','price']][autos['price'] ==
autos['price'].max()]
print(plus_chere)
# SQL equivalent : SELECT company, horsepower, price FROM autos WHERE price =
MAX(price)
# Q4 : Toutes les Toyota (deux methodes)
# Methode 1 : filtrage direct
toyota_df = autos[autos['company'] == 'toyota']
# Methode 2 : groupby + get_group
liste_par_marque = [Link]('company')
toyota_df = liste_par_marque.get_group('toyota')
print(toyota_df)
# Q5 : Nombre de voitures par compagnie
print(autos['company'].value_counts())
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 4
# Q6 : Prix max par compagnie
prix_max = liste_par_marque['price'].max()
print(prix_max)
# Q7 : Moyenne de kilometrage par compagnie
mileage_moyen = liste_par_marque['average-mileage'].mean()
print(mileage_moyen)
# Q8 : Trier par prix et chevaux
tri = autos.sort_values(by=['price','horsepower'], ascending=False)
print([Link](5))
3.3 Recapitulatif des patterns utilises
Operation Code Python
Valeur max d'une colonne df['col'].max()
Ligne avec valeur max df[df['col'] == df['col'].max()]
Filtrer sur une valeur df[df['company'] == 'toyota']
Grouper + obtenir un groupe groupby('col').get_group('valeur')
Compter par categorie df['col'].value_counts()
Max par groupe groupby('col')['val'].max()
Moyenne par groupe groupby('col')['val'].mean()
Trier par colonnes sort_values(by=['col1','col2'],
ascending=False)
Selectionner colonnes df[['col1','col2','col3']]
ASTUCE EXAM : Pour 'la voiture la plus chere', toujours faire :
df[df['price'] == df['price'].max()] et non df.sort_values('price').tail(1)
La premiere methode retourne TOUTES les voitures au prix max (il peut y en avoir plusieurs).
4. PROJET 2 — ANALYSE DES VENTES
4.1 Structure des donnees
12 fichiers CSV mensuels (janvier a decembre 2019). Colonnes : Order ID, Product, Quantity Ordered,
Price Each, Order Date, Purchase Address.
4.2 Etape 1 : Fusionner tous les fichiers CSV
import os
import pandas as pd
path = './Data'
Global = [Link]()
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 5
files = [f for f in [Link](path) if [Link]('.csv')]
for fichier in files:
df_local = pd.read_csv(path + '/' + fichier)
Global = [Link]([Global, df_local])
Global.to_csv('all_data_copy.csv', index=False)
print([Link]) # verifier : ~200 000 lignes x 6 colonnes
4.3 Etape 2 : Nettoyage
DF = pd.read_csv('all_data_copy.csv')
# 1. Recensement des valeurs manquantes
print([Link]().sum()) # NaN par colonne
print([Link]) # dimensions avant nettoyage
# 2. Supprimer les lignes entierement vides
[Link](how='all', inplace=True)
print([Link]) # dimensions apres
# 3. Supprimer les lignes erronees dans 'Order Date'
# Probleme : certaines lignes contiennent 'Order Date' dans la colonne Order Date
# (c'est l'en-tete repete apres concatenation)
DF = DF[DF['Order Date'].str[0:2] != 'Or']
print('Nettoyage termine')
# 4. Supprimer les doublons
DF.drop_duplicates(inplace=True)
ASTUCE IMPORTANTE : Apres [Link]() sur plusieurs CSV,
les en-tetes ('Order ID', 'Order Date'...) se repetent comme des lignes de donnees !
Solution : DF = DF[DF['Order Date'].str[0:2] != 'Or']
=> Supprime toutes les lignes dont les 2 premiers caracteres de 'Order Date' sont 'Or'
4.4 Etape 3 : Conversion des types et enrichissement
# Convertir les types
DF['Order Date'] = pd.to_datetime(DF['Order Date'])
DF['Quantity Ordered']= pd.to_numeric(DF['Quantity Ordered'])
DF['Price Each'] = pd.to_numeric(DF['Price Each'])
print([Link]) # verification
# Ajouter colonne 'Mois' (extraire depuis la date)
DF['Mois'] = DF['Order Date'].[Link]
# Ou en string : DF['Mois'] = DF['Order Date'].dt.to_period('M')
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 6
# Ajouter colonne 'Heure' (pour analyse temporelle)
DF['Heure'] = DF['Order Date'].[Link]
# Ajouter colonne 'City/State' (extraire depuis Purchase Address)
# Format adresse : '136 Church St, New York City, NY 10001'
DF['City/State'] = DF['Purchase Address'].apply(
lambda x: [Link](',')[1].strip() + ', ' + [Link](',')[2].strip().split(' ')
[1]
)
# Resultat : 'New York City, NY'
# Ajouter colonne 'Total' (montant total de chaque ligne)
DF['Total'] = DF['Quantity Ordered'] * DF['Price Each']
PROPRIETES DATETIME ESSENTIELLES (apres pd.to_datetime) :
.[Link] => numero du mois (1-12)
.[Link] => jour du mois (1-31)
.[Link] => heure (0-23)
.[Link] => annee
.[Link] => jour de la semaine (0=lundi, 6=dimanche)
4.5 Etape 4 : Exploration et requetes
Requete 1 : Meilleur mois de vente
# Calculer le total des ventes par mois
ventes_par_mois = [Link]('Mois')['Total'].sum()
print(ventes_par_mois)
# Trouver le mois avec le maximum
meilleur_mois = ventes_par_mois.idxmax()
print('Meilleur mois :', meilleur_mois)
print('Revenu :', ventes_par_mois.max())
# Visualisation
import [Link] as plt
ventes_par_mois.plot(kind='bar', title='Ventes par mois')
[Link]('Mois')
[Link]('Total des ventes')
[Link]()
Requete 2 : Ville avec le maximum de revenus
# Agregation des ventes par ville
ventes_par_ville = [Link]('City/State')['Total'].sum()
print(ventes_par_ville.sort_values(ascending=False))
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 7
# Ville avec le max
meilleure_ville = ventes_par_ville.idxmax()
print('Meilleure ville :', meilleure_ville)
# Visualisation
ventes_par_ville.sort_values(ascending=False).plot(kind='bar')
[Link]('Revenus par ville')
[Link](rotation=45)
[Link]()
Requete 3 : Meilleure heure pour les publicites
# Compter les achats par heure
achats_par_heure = [Link]('Heure')['Order ID'].count()
print(achats_par_heure)
# Heure avec le plus d'achats
meilleure_heure = achats_par_heure.idxmax()
print('Meilleure heure :', meilleure_heure, 'h')
# Visualisation
achats_par_heure.plot(kind='line', title='Achats par heure')
[Link]('Heure de la journee')
[Link]('Nombre de commandes')
[Link]()
Requete 4 : Produit le plus vendu
# Compter la quantite totale vendue par produit
ventes_par_produit = [Link]('Product')['Quantity Ordered'].sum()
print(ventes_par_produit.sort_values(ascending=False))
# Produit le plus vendu
print('Produit le plus vendu :', ventes_par_produit.idxmax())
# Visualisation
ventes_par_produit.sort_values(ascending=False).plot(kind='bar')
[Link]('Quantite vendue par produit')
[Link](rotation=45)
plt.tight_layout()
[Link]()
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 8
5. OPERATIONS PANDAS AVANCEES — A MAITRISER
5.1 .apply() avec lambda — Transformation personnalisee
apply() applique une fonction a chaque element d'une colonne. Tres puissant pour les transformations
complexes.
# Syntaxe de base
df['nouvelle_col'] = df['col'].apply(lambda x: x * 2)
# Extraire une partie d'une chaine
# Adresse : '136 Church St, New York City, NY 10001'
df['Ville'] = df['Adresse'].apply(lambda x: [Link](',')[1].strip())
# => 'New York City'
# Extraire l'etat
df['Etat'] = df['Adresse'].apply(lambda x: [Link](',')[2].strip().split(' ')[1])
# => 'NY'
# Application conditionnelle
df['Categorie'] = df['Prix'].apply(lambda x: 'Cher' if x > 1000 else 'Accessible')
# Avec fonction nommee
def extraire_ville(adresse):
return [Link](',')[1].strip()
df['Ville'] = df['Adresse'].apply(extraire_ville)
5.2 Proprietes .str — Operations sur les chaines
# Verifier le contenu d'une colonne chaine
df['Order Date'].str[0:2] # 2 premiers caracteres
df['col'].[Link]('texte') # True si contient 'texte'
df['col'].[Link]('Or') # True si commence par 'Or'
df['col'].[Link]() # mettre en majuscules
df['col'].[Link]() # mettre en minuscules
df['col'].[Link]() # supprimer espaces debut/fin
df['col'].[Link](',') # decouper par ','
df['col'].[Link]() # longueur de chaque chaine
# Filtrer des lignes avec .str
df[df['Order Date'].str[0:2] != 'Or'] # exclure les en-tetes repetes
df[df['col'].[Link]('Toyota')] # garder les lignes avec 'Toyota'
5.3 .idxmax() et .idxmin() — Trouver le label du max/min
s = [Link]({'Jan': 1000, 'Feb': 800, 'Mar': 1500, 'Apr': 1200})
[Link]() # 1500 (la valeur maximale)
[Link]() # 'Mar' (le LABEL de la valeur maximale)
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 9
[Link]() # 800
[Link]() # 'Feb'
# Sur un DataFrame : index de la ligne avec le max d'une colonne
df['price'].idxmax() # index de la ligne avec le prix max
# Utilisation typique en analyse
ventes_par_mois = [Link]('Mois')['Total'].sum()
meilleur_mois = ventes_par_mois.idxmax() # => 12 (decembre, par exemple)
5.4 .value_counts() — Comptage rapide
# Compter les occurrences de chaque valeur unique
df['company'].value_counts()
# Resultat trie par frequence decroissante
# Avec normalisation (proportions en %)
df['company'].value_counts(normalize=True) * 100
# Equivalent groupby
[Link]('company').size().sort_values(ascending=False)
5.5 .sort_values() — Tri avance
# Tri par une seule colonne
df.sort_values('price') # ascendant par defaut
df.sort_values('price', ascending=False) # descendant
# Tri par plusieurs colonnes
df.sort_values(by=['price', 'horsepower'], ascending=False)
df.sort_values(by=['company', 'price'], ascending=[True, False])
# company ascendant, price descendant
# Ne pas oublier : sort_values retourne un NOUVEAU DataFrame
# Pour modifier en place :
df.sort_values('price', inplace=True)
5.6 .groupby() avec .get_group()
# Grouper et extraire un groupe specifique
groupes = [Link]('company')
# Obtenir le sous-DataFrame d'un groupe
toyota = groupes.get_group('toyota')
# Equivalent par filtrage direct
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 10
toyota = df[df['company'] == 'toyota']
# Les deux methodes donnent le meme resultat.
# get_group() est plus lisible quand on a deja le groupby.
# Lister les noms des groupes
print([Link]())
6. VISUALISATION AVEC MATPLOTLIB
6.1 Types de graphiques
Type Code
Barres verticales [Link](kind='bar') ou [Link](x, y)
Barres horizontales [Link](kind='barh')
Courbe / Ligne [Link](kind='line') ou [Link](x, y)
Nuage de points [Link](kind='scatter', x='col1', y='col2')
Histogramme df['col'].plot(kind='hist', bins=20)
Camembert [Link](kind='pie', y='col')
Aire [Link](kind='area')
6.2 Personnaliser les graphiques
import [Link] as plt
# Graphique de base
ventes_par_mois.plot(kind='bar', color='steelblue', figsize=(10, 6))
# Titres et labels
[Link]('Ventes mensuelles 2019', fontsize=16)
[Link]('Mois')
[Link]('Revenus ($)')
# Rotation des labels de l'axe x
[Link](rotation=45)
# Ajuster les marges automatiquement
plt.tight_layout()
# Afficher
[Link]()
# Sauvegarder
[Link]('[Link]', dpi=150)
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 11
7. RECAP : PIPELINE COMPLET D'ANALYSE
7.1 Les 6 etapes d'un projet Data
# Etape Details
1 Charger pd.read_csv() / [Link]() / [Link]()
2 Explorer head(), dtypes, shape, describe(), isnull().sum()
3 Nettoyer dropna(), fillna(), drop_duplicates(), filtrage str
4 Transformer astype(), pd.to_datetime(), [Link], apply(lambda)
5 Analyser groupby(), pivot_table(), sort_values(), value_counts()
6 Visualiser plot(kind='bar/line/scatter'), [Link]/xlabel, [Link]()
7.2 Fonctions indispensables — Recap final
Operation Syntaxe Resultat
Valeur max df['col'].max() Valeur maximale
Label du max df['col'].idxmax() Index/label de la valeur
max
Ligne avec le max df[df['col']==df['col'].max() DataFrame filtre
]
Compter par categorie df['col'].value_counts() Serie triee par frequence
Grouper + agregat [Link]('col') Serie par groupe
['val'].sum()
Extraction de date df['date'].[Link] Colonne des mois
Extraction chaine df['col'].apply(lambda x: Partie de la chaine
[Link](',')[1])
Filtrer chaine df[df['col'].str[0:2]!='Or'] Supprimer lignes erronnees
Concatener CSVs [Link]([df1, df2]) DataFrame fusionné
Sauvegarder CSV df.to_csv('[Link]', Fichier CSV
index=False)
Trier df.sort_values('col', DataFrame trie
ascending=False)
8. PIEGES FREQUENTS — JOURNEE 4
PIEGE 1 : En-tetes repetes apres [Link]()
Concatener plusieurs CSV avec les memes colonnes => l'en-tete se repete comme une ligne !
Solution : DF = DF[DF['Order Date'].str[0:2] != 'Or']
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 12
PIEGE 2 : index=False dans to_csv()
df.to_csv('[Link]') => sauvegarde l'index (colonne 'Unnamed: 0' a la relecture !)
df.to_csv('[Link]', index=False) => sans l'index (toujours utiliser cette option)
PIEGE 3 : pd.to_numeric() vs astype()
pd.to_numeric(col, errors='coerce') => convertit les erreurs en NaN (plus sur)
.astype('float64') => leve une erreur si une valeur ne peut pas etre convertie
PIEGE 4 : .apply(lambda) sur les chaines
[Link](',')[1] peut lever une IndexError si la chaine n'a pas de virgule !
Toujours tester sur un echantillon avant d'appliquer a tout le DataFrame.
PIEGE 5 : idxmax() vs max()
df['col'].max() => retourne la VALEUR maximale (ex: 1 500 000)
df['col'].idxmax() => retourne le LABEL de la ligne avec la valeur max (ex: 'Dec')
PIEGE 6 : groupby sur plusieurs colonnes
liste_par_marque['price','horsepower'].max() => OBSOLETE en pandas recent !
Syntaxe correcte : liste_par_marque[['price','horsepower']].max() (double crochet)
PIEGE 7 : reset_index() apres groupby
groupby().sum() cree un index = les valeurs groupees.
Pour avoir un DataFrame normal avec index 0,1,2... : .reset_index() apres l'agregation.
Bonne chance a l'examen !
Guide Python 3 — Journee 4 : Pandas Applique & Projets | Page 13