Cet article décrit les principales fonctionnalités de la bibliothèque Pandas. Je te montre à quel point cet outil peut te faire économiser du temps et des efforts dans tes projets de data science.
J’ai divisé l’article en trois sections. Bonne lecture 🙂
En bref : Pandas est une bibliothèque Python open source, créée à partir de 2008 par Wes McKinney et construite sur NumPy, qui introduit deux structures de données : la Series (unidimensionnelle) et le DataFrame (un tableau avec lignes et colonnes). Ce guide couvre l’installation, la lecture de fichiers CSV et Excel, la sélection, le tri, les valeurs manquantes, le groupby, le filtrage, la fusion et les graphiques.
Tu peux aussi exécuter tous ces exemples dans ce notebook Google Colab : chaque extrait de code est dans sa propre cellule, prêt à être modifié.
Pour mettre tout ça en pratique sur des jeux de données réels, le parcours Analyse et visualisation des données de DataXp te fait manipuler des DataFrames sur des exercices guidés, avec un coach IA.
Section 1 : Qu’est-ce que la bibliothèque Pandas ?
Cette section présente la bibliothèque Pandas et met en évidence ses deux structures de données les plus importantes.
Pandas, c’est quoi ?
- Une des bibliothèques Python les plus utilisées pour la Data Science.
- Créé à partir de 2008 par Wes McKinney
- Open source
- Construit sur NumPy, avec des parties écrites en Cython et en C : d’où sa rapidité
- A introduit les objets DataFrame et Series
Comment je l’installe ?
Le moyen le plus simple est d’installer Anaconda, qui inclut directement toutes les bibliothèques scientifiques standard dont Pandas fait partie.
Sinon, Pandas s’installe avec pip depuis PyPI :
pip install pandasQu’est-ce qu’un objet Series ?
- Un objet Series est unidimensionnel, comme un tableau. C’est un objet mutable : il peut être mis à jour, de nouveaux éléments peuvent être ajoutés et des éléments existants peuvent être supprimés.
- Il peut contenir des données de tout type.
- Il peut être instancié avec un tableau ou un dictionnaire. Dans ce cas, les clés du dictionnaire servent d’index.
- Le constructeur
pd.Seriesaccepte les données, l’index, le type de données (dtype) et un booléen indiquant s’il faut copier les données (copy). Sans noms d’index, les index sont des entiers à partir de 0. - Considère un objet Series comme une colonne verticale pouvant contenir plusieurs lignes.
Créer une Series
import pandas as pd
series = pd.Series(data=[111, 222, 3], index = ['un','deux','trois'])
# ou series = pd.Series([111, 222, 3])PythonRécupérer des données d’une Series
On peut sélectionner des éléments par leur nom d’index, ou par leur position avec iloc. Note : avec Pandas 3, series[0] ne fonctionne plus quand l’index est composé de textes, d’où l’usage de iloc :
print(series['deux'])
# ou
print(series.iloc[0])
# plusieurs éléments
print(series[['un','trois']])Python222
111
un 111
trois 3
dtype: int64Qu’est-ce qu’un objet DataFrame ?
- La structure de données la plus utilisée dans un projet de Data Science.
- C’est un tableau avec des lignes et des colonnes, comme une table SQL ou une feuille de calcul Excel.
- Les colonnes peuvent avoir des types différents (entiers, texte, dates…).
- Offre une analyse de séries chronologiques très performante.
- Un DataFrame contient une ou plusieurs Series.
- Un DataFrame est mutable.
Voici schématiquement à quoi ressemble un DataFrame :
| ColonneA | ColonneB | ColonneC | ColonneD | |
|---|---|---|---|---|
| index0 | ||||
| index1 | ||||
| index2 | ||||
| index3 | ||||
| index4 |
Créer un DataFrame
Il existe plusieurs façons de créer un DataFrame : à partir d’un tableau, d’un dictionnaire, d’une liste, d’une Series ou même d’un autre DataFrame.
Ici, je crée un DataFrame à partir de Series :
import pandas as pd
d = {'ColonneA' : pd.Series([111, 222, 333]),
'ColonneB' : pd.Series([444, 555, 666])}
df = pd.DataFrame(d)PythonLe DataFrame ci-dessus contient deux colonnes nommées ColonneA et ColonneB :
ColonneAcontient trois lignes : 111, 222 et 333.ColonneBcontient trois lignes : 444, 555 et 666.
Sélection de colonne(s)
On utilise le nom de la colonne pour obtenir ses données :
data = df['ColonneA']
dataPython0 111
1 222
2 333
Name: ColonneA, dtype: int64Pour supprimer une colonne, on peut utiliser pop (qui retire la colonne et la renvoie) ou drop.
Sélection de ligne(s)
Si une ligne a une étiquette, on utilise loc :
# On donne d'abord des étiquettes aux lignes
df_labels = df.set_index(pd.Index(['label1', 'label2', 'label3']))
# 'label1' est un exemple d'étiquette de ligne
data = df_labels.loc['label1']
print(data)
# Plusieurs lignes
data = df_labels.loc[['label1', 'label2']]
dataPythonColonneA 111
ColonneB 444
Name: label1, dtype: int64
ColonneA ColonneB
label1 111 444
label2 222 555Sinon, on peut utiliser la position de la ligne avec iloc :
data = df.iloc[0] # retourne la ligne à la position 0 (la première)
dataPythonColonneA 111
ColonneB 444
Name: 0, dtype: int64Pour supprimer une ligne, on utilise drop.
Sur un DataFrame, on peut appliquer de nombreuses opérations : fusionner des colonnes, effectuer des calculs mathématiques sur les lignes et/ou les colonnes, ou encore travailler sur des sous-ensembles.
Chaque colonne est indexée.
Renommer un nom de colonne
On utilise rename(columns, index, inplace=False) pour renommer les colonnes d’un DataFrame. Avec inplace=True, le DataFrame est modifié directement et la fonction ne renvoie rien. Avec inplace=False (valeur par défaut), elle renvoie une copie renommée.
Par exemple, pour renommer ColonneA en A :
df_renamed = df.rename(columns={'ColonneA': 'A'})
df_renamedPython A ColonneB
0 111 444
1 222 555
2 333 666Réindexer
Pour réindexer (changer les étiquettes des lignes ou des colonnes), on utilise la méthode reindex.
Itérer sur les colonnes d’un DataFrame
Pour parcourir les colonnes d’un DataFrame :
for column in df:
print(column)PythonColonneA
ColonneBOn peut aussi parcourir les colonnes avec leur contenu, avec items() (anciennement iteritems(), supprimée dans Pandas 2.0) :
for column,items in df.items():
print(column, items)PythonColonneA 0 111
1 222
2 333
Name: ColonneA, dtype: int64
ColonneB 0 444
1 555
2 666
Name: ColonneB, dtype: int64Pour parcourir les lignes, avec iterrows() :
for index_of_row, row in df.iterrows():
print(index_of_row, row)Python0 ColonneA 111
ColonneB 444
Name: 0, dtype: int64
1 ColonneA 222
ColonneB 555
Name: 1, dtype: int64
2 ColonneA 333
ColonneB 666
Name: 2, dtype: int64itertuples() renvoie chaque ligne sous la forme d’un tuple nommé (généralement plus rapide que iterrows()) :
for row in df.itertuples():
print(row)PythonPandas(Index=0, ColonneA=111, ColonneB=444)
Pandas(Index=1, ColonneA=222, ColonneB=555)
Pandas(Index=2, ColonneA=333, ColonneB=666)Un DataFrame est très puissant : on peut facilement trier les éléments par lignes et par colonnes.
Trier par ligne(s)
On peut trier selon l’index des lignes avec sort_index() :
sorted_dataframe = df.sort_index()
sorted_dataframePython ColonneA ColonneB
0 111 444
1 222 555
2 333 666Trier par colonne(s)
Pour trier les colonnes selon leur nom, on utilise sort_index(axis=1).
Pour trier selon les valeurs d’une ou plusieurs colonnes, on utilise sort_values(by=...) :
sorted_dataframe = df.sort_values(by='ColonneA')
sorted_dataframePython ColonneA ColonneB
0 111 444
1 222 555
2 333 666Les fonctions qu’on applique à des chaînes de caractères peuvent aussi s’appliquer aux colonnes d’un DataFrame, grâce à l’accesseur .str : str.lower(), str.upper(), str.len(), str.strip(), etc.
Section 2 : Quelles sont les fonctionnalités de base de Pandas ?
Cette section présente les fonctionnalités indispensables de Pandas. La plupart des cas courants de manipulation de données peuvent être traités avec les fonctionnalités de base décrites ici.
Comment lire un fichier CSV avec Pandas ?
Pour les exemples de cette section, je crée d’abord un petit fichier CSV et un fichier Excel, avec quelques valeurs manquantes :
# Création d'un petit fichier CSV et d'un fichier Excel d'exemple (avec quelques valeurs manquantes)
import pandas as pd
source = pd.DataFrame({
"ColonneA": [111, 222, 333, 444, 555, 666],
"ColonneB": [444, None, 666, 777, None, 999],
})
source.to_csv("fichier.csv", index=False)
source.to_excel("fichier_Excel.xlsx", sheet_name="Sheet1", index=False)
sourcePython ColonneA ColonneB
0 111 444.0
1 222 NaN
2 333 666.0
3 444 777.0
4 555 NaN
5 666 999.0Commençons par la tâche la plus courante : lire un fichier CSV et en faire un DataFrame :
dataFrame = pd.read_csv("fichier.csv", index_col=['ColonneA'])
dataFramePython ColonneB
ColonneA
111 444.0
222 NaN
333 666.0
444 777.0
555 NaN
666 999.0Comment lire un fichier Excel avec Pandas ?
On peut lire un fichier Excel dans un DataFrame (il faut avoir installé openpyxl avec pip install openpyxl) :
dataFrame = pd.read_excel('fichier_Excel.xlsx', index_col='ColonneA')
dataFramePython ColonneB
ColonneA
111 444.0
222 NaN
333 666.0
444 777.0
555 NaN
666 999.0On peut aussi charger une feuille précise du fichier Excel :
dataFrame = pd.read_excel('fichier_Excel.xlsx', sheet_name='Sheet1')
dataFramePython ColonneA ColonneB
0 111 444.0
1 222 NaN
2 333 666.0
3 444 777.0
4 555 NaN
5 666 999.0Head
Pour la suite, on recharge le fichier CSV sans index_col, afin que ColonneA reste une colonne ordinaire. head(n) renvoie les n premières lignes d’un DataFrame :
dataFrame = pd.read_csv("fichier.csv")
r = dataFrame.head(10) # retourne les 10 premières lignes du DataFrame
rPython ColonneA ColonneB
0 111 444.0
1 222 NaN
2 333 666.0
3 444 777.0
4 555 NaN
5 666 999.0Tail
tail(n) renvoie les n dernières lignes d’un DataFrame :
r = dataFrame.tail(10) # retourne les 10 dernières lignes du DataFrame
rPython ColonneA ColonneB
0 111 444.0
1 222 NaN
2 333 666.0
3 444 777.0
4 555 NaN
5 666 999.0Transposée
Pour échanger les lignes et les colonnes (transposée), on utilise l’attribut T :
transposed = dataFrame.T
transposedPython 0 1 2 3 4 5
ColonneA 111.0 222.0 333.0 444.0 555.0 666.0
ColonneB 444.0 NaN 666.0 777.0 NaN 999.0Il existe aussi des attributs clés à connaître :
shape– dimension du DataFrame (nombre de lignes et de colonnes)size– nombre d’élémentsndim– nombre d’axes
Describe
Pour obtenir un résumé rapide de ton DataFrame (moyenne, écart type, minimum, maximum… de chaque colonne), on utilise la méthode describe() :
dataFrame.describe()Python ColonneA ColonneB
count 6.000000 4.000000
mean 388.500000 721.500000
std 207.661985 231.064926
min 111.000000 444.000000
25% 249.750000 610.500000
50% 388.500000 721.500000
75% 527.250000 832.500000
max 666.000000 999.000000Un DataFrame offre aussi de nombreuses fonctions statistiques :
abs()– valeurs absoluesmean()– moyenne ; il existe aussimedian()(médiane) etmode()(mode)min()– valeur minimale (etmax())count()(nombre de valeurs),std()(écart type),prod()(produit des valeurs),cumsum()(sommes cumulées), etc.
Remarque : avec Pandas 3, si le DataFrame contient aussi des colonnes de texte, ajoute numeric_only=True (par exemple dataFrame.mean(numeric_only=True)).
Parfois, on veut appliquer ses propres fonctions…
Fonction sur un DataFrame
Pour appliquer une fonction personnalisée à l’ensemble d’un DataFrame, on utilise la méthode pipe() :
def myCustom(a, b):
return a - b
dataFrame.pipe(myCustom, 1) # le dernier paramètre (1) est la valeur de b dans la fonction myCustomPython ColonneA ColonneB
0 110 443.0
1 221 NaN
2 332 665.0
3 443 776.0
4 554 NaN
5 665 998.0Fonction sur une ligne/colonne
Pour appliquer une fonction à une ligne ou à une colonne, utilise apply().
Ceci applique la fonction myCustom à toutes les colonnes :
def myCustom(a):
return a - 1
dataFrame.apply(myCustom)Python ColonneA ColonneB
0 110 443.0
1 221 NaN
2 332 665.0
3 443 776.0
4 554 NaN
5 665 998.0Pour l’appliquer à chaque ligne, on fixe axis=1 :
dataFrame.apply(myCustom, axis=1)Python ColonneA ColonneB
0 110.0 443.0
1 221.0 NaN
2 332.0 665.0
3 443.0 776.0
4 554.0 NaN
5 665.0 998.0Pour l’appliquer à chaque colonne, on fixe axis=0 :
dataFrame.apply(myCustom, axis=0) # axis=0 est la valeur par défautPython ColonneA ColonneB
0 110 443.0
1 221 NaN
2 332 665.0
3 443 776.0
4 554 NaN
5 665 998.0Section 3 : Quelles fonctionnalités avancées de Pandas utiliser ?
Pandas est une bibliothèque fantastique pour l’analyse de données. Cette section présente des fonctionnalités utiles pour mener un projet de data science.
Dans un tel projet, on est souvent confronté à des données manquantes. Pour les gérer, on peut les supprimer, les remplacer par une valeur prédéfinie ou les compléter avec la valeur précédente ou suivante.
Comment repérer les valeurs manquantes ?
dataFrame.isna() # True pour chaque valeur manquantePython ColonneA ColonneB
0 False False
1 False True
2 False False
3 False False
4 False True
5 False FalsedataFrame.notnull() # l'inverse : True pour chaque valeur présentePython ColonneA ColonneB
0 True True
1 True False
2 True True
3 True True
4 True False
5 True TrueSupprimer les valeurs manquantes
dataFrame.dropna()Python ColonneA ColonneB
0 111 444.0
2 333 666.0
3 444 777.0
5 666 999.0Remplir les valeurs manquantes (les remplacer directement)
dataFrame.fillna(0) # même valeur partoutPython ColonneA ColonneB
0 111 444.0
1 222 0.0
2 333 666.0
3 444 777.0
4 555 0.0
5 666 999.0dataFrame.fillna({'ColonneA': 0, 'ColonneB': 99}) # une valeur par colonnePython ColonneA ColonneB
0 111 444.0
1 222 99.0
2 333 666.0
3 444 777.0
4 555 99.0
5 666 999.0On peut aussi passer un dictionnaire à fillna() pour définir une valeur par colonne, ou utiliser replace() pour remplacer des valeurs précises.
Remplir les valeurs manquantes – en amont ou en aval
dataFrame.ffill() # remplit avec la valeur précédentePython ColonneA ColonneB
0 111 444.0
1 222 444.0
2 333 666.0
3 444 777.0
4 555 777.0
5 666 999.0dataFrame.bfill() # remplit avec la valeur suivantePython ColonneA ColonneB
0 111 444.0
1 222 666.0
2 333 666.0
3 444 777.0
4 555 999.0
5 666 999.0Comparaison des éléments en pourcentage
On peut comparer les éléments d’un DataFrame et calculer la variation en pourcentage de chaque élément par rapport au précédent :
dataFrame.pct_change() # par colonnePython ColonneA ColonneB
0 NaN NaN
1 1.000000 NaN
2 0.500000 NaN
3 0.333333 0.166667
4 0.250000 NaN
5 0.200000 NaNdataFrame.pct_change(axis=1) # par lignePython ColonneA ColonneB
0 NaN 3.00
1 NaN NaN
2 NaN 1.00
3 NaN 0.75
4 NaN NaN
5 NaN 0.50Calcul de l’écart-type
std() calcule l’écart-type de chaque colonne. Son carré donne la variance (ou utilise directement var()) :
dataFrame.std() # écart-type de chaque colonnePythonColonneA 207.661985
ColonneB 231.064926
dtype: float64dataFrame.var() # variance de chaque colonnePythonColonneA 43123.5
ColonneB 53391.0
dtype: float64Calcul de la covariance
Pour calculer la covariance entre deux colonnes d’un DataFrame :
dataFrame.cov() # entre toutes les colonnesPython ColonneA ColonneB
ColonneA 43123.5 53391.0
ColonneB 53391.0 53391.0dataFrame['ColonneA'].cov(dataFrame['ColonneB']) # entre 2 colonnesPythonnp.float64(53391.0)Calcul de la corrélation
dataFrame.corr() # entre toutes les colonnesPython ColonneA ColonneB
ColonneA 1.0 1.0
ColonneB 1.0 1.0dataFrame['ColonneA'].corr(dataFrame['ColonneB']) # entre 2 colonnesPythonnp.float64(1.0)Colonnes d’agrégation
On peut appliquer une ou plusieurs fonctions à plusieurs colonnes d’un DataFrame avec aggregate() (ou agg()) :
dataFrame.aggregate({'ColonneA': ['sum', 'mean'], 'ColonneB': 'max'})Python ColonneA ColonneB
sum 2331.0 NaN
mean 388.5 NaN
max NaN 999.0Comment grouper des lignes avec groupby() ?
Pour regrouper des lignes, on utilise la fonction groupby() :
dataFrame['NomColonne'] = ['x', 'y', 'x', 'y', 'x', 'y'] # colonne ajoutée pour l'exemple
groupedDataFrame = dataFrame.groupby('NomColonne')PythonPour voir les groupes :
groupedDataFrame.groupsPython{'x': [0, 2, 4], 'y': [1, 3, 5]}Pour sélectionner un groupe :
groupedDataFrame.get_group('x')Python ColonneA ColonneB NomColonne
0 111 444.0 x
2 333 666.0 x
4 555 NaN xOn peut aussi grouper sur plusieurs colonnes ; ngroups donne le nombre de groupes obtenus :
groupedDataFrame2 = dataFrame.groupby(['ColonneA', 'ColonneB'])
groupedDataFrame2.ngroupsPython4Comment filtrer un DataFrame ?
Il existe trois façons courantes de filtrer, selon ce que l’on veut garder.
Pour filtrer des lignes selon une condition, on utilise l’indexation booléenne :
dataFrame[dataFrame['ColonneA'] > 100]Python ColonneA ColonneB NomColonne
0 111 444.0 x
1 222 NaN y
2 333 666.0 x
3 444 777.0 y
4 555 NaN x
5 666 999.0 yPour filtrer des groupes entiers, on utilise filter() sur un objet groupby, avec une fonction qui renvoie True ou False pour chaque groupe :
groupedDataFrame.filter(lambda groupe: groupe['ColonneB'].mean() > 100)Python ColonneA ColonneB NomColonne
0 111 444.0 x
1 222 NaN y
2 333 666.0 x
3 444 777.0 y
4 555 NaN x
5 666 999.0 yEnfin, DataFrame.filter() sert à sélectionner des colonnes d’après leur nom :
dataFrame.filter(like='Colonne') # colonnes dont le nom contient 'Colonne'Python ColonneA ColonneB NomColonne
0 111 444.0 x
1 222 NaN y
2 333 666.0 x
3 444 777.0 y
4 555 NaN x
5 666 999.0 yComment fusionner deux DataFrames avec merge() ?
La fusion de deux DataFrames est probablement l’une des tâches les plus importantes en Data Science. Pandas propose des fonctionnalités permettant de joindre plusieurs DataFrames sur la base de jointures gauche, droite, intérieure et extérieure.
La fonction à utiliser est merge(). Elle prend en paramètres le DataFrame de gauche, le DataFrame de droite, le paramètre on (les colonnes de jointure) et le paramètre how, qui décrit le type de jointure : left (gauche), right (droite), outer (extérieure) ou inner (intérieure).
Remarque : pour choisir des colonnes différentes dans les DataFrames de gauche et de droite, utilise les paramètres left_on et right_on avec les noms des colonnes (ce peut être une liste de colonnes).
# Deux petits DataFrames à fusionner
left = pd.DataFrame({'name': ['Alice', 'Bob', 'Chloé'], 'ville': ['Paris', 'Lyon', 'Nice']})
right = pd.DataFrame({'id': ['Alice', 'Bob', 'David'], 'salaire': [3000, 3500, 4000]})
merged = pd.merge(left,right,left_on='name',right_on='id', how='left')
mergedPython name ville id salaire
0 Alice Paris Alice 3000.0
1 Bob Lyon Bob 3500.0
2 Chloé Nice NaN NaNUnir deux DataFrames
Pour concaténer deux DataFrames, on utilise la fonction concat(). Avec axis=1, ils sont placés côte à côte au lieu d’être empilés :
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
pd.concat([df1, df2]) # l'un en dessous de l'autrePython A B
0 1 3
1 2 4
0 5 7
1 6 8pd.concat([df1, df2], axis=1) # côte à côtePython A B A B
0 1 3 5 7
1 2 4 6 8Opérations sur les dates
Pandas sait aussi manipuler les dates. Par exemple, date_range() génère une plage de dates :
pd.date_range(start='2024-01-01', end='2024-01-10')PythonDatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
'2024-01-05', '2024-01-06', '2024-01-07', '2024-01-08',
'2024-01-09', '2024-01-10'],
dtype='datetime64[us]', freq='D')Graphiques
Les DataFrames offrent des options pour tracer des graphiques : courbes, boîtes à moustaches, surfaces, nuages de points, graphiques empilés, diagrammes à barres, histogrammes, etc. (Matplotlib doit être installé.)
dataFrame.plot.bar() # diagramme à barresPython
dataFrame.hist(bins=10) # histogrammesPython
dataFrame.plot.scatter(x='ColonneA', y='ColonneB') # nuage de pointsPython
Questions fréquentes sur la bibliothèque Pandas
Qu’est-ce que Pandas en Python ?
Pandas est une des bibliothèques Python les plus utilisées pour la data science. Open source, créée à partir de 2008 par Wes McKinney, elle est construite sur NumPy, avec des parties écrites en Cython et en C, ce qui la rend rapide. Elle a introduit les objets DataFrame et Series.
Quelle est la différence entre une Series et un DataFrame ?
Une Series est unidimensionnelle, comme une colonne verticale. Un DataFrame est un tableau avec des lignes et des colonnes, comme une table SQL ou une feuille Excel, dont les colonnes peuvent avoir des types différents. Un DataFrame contient une ou plusieurs Series. Les deux sont mutables.
Comment installer Pandas ?
Le plus simple est d’installer Anaconda, qui inclut déjà Pandas et les autres bibliothèques scientifiques standard. Sinon, Pandas s’installe avec pip depuis PyPI.
Comment fusionner deux DataFrames avec Pandas ?
Avec merge(), qui prend le DataFrame de gauche, celui de droite, le paramètre on (les colonnes de jointure) et le paramètre how : left, right, outer ou inner. Pour des colonnes de jointure différentes à gauche et à droite, utilise left_on et right_on. Pour empiler ou juxtaposer deux DataFrames, utilise concat().
Comment gérer les valeurs manquantes avec Pandas ?
Tu peux les supprimer (dropna()), les remplacer par une valeur prédéfinie avec fillna() (ou un dictionnaire pour une valeur par colonne), ou les compléter avec la valeur précédente ou suivante.
Conclusion
Cet article n’est qu’un aperçu de la puissance de la bibliothèque Pandas, mais il constitue une bonne boîte à outils des « indispensables ».
Pour aller plus loin, lis notre article sur les 12 techniques de manipulation de données avec Pandas.
Pour aller plus loin avec Pandas, consulte aussi notre guide des astuces Pandas en Python. Pour progresser en Python, découvre aussi nos 21 astuces et concepts Python pour améliorer ton code.













