Tuto Python & pandas : installation et manipulations de base
Rédigé par Sami Nadif, Publié le 24 Novembre 2020, Mise à jour le Mardi, 24 Novembre 2020 22:50
Table des matières
1.1. Composantes essentielles de pandas : Series et DataFrames
1.2. Lire des fichiers de données
2.2. Générer de nouvelles colonnes
2.3. Obtenir des informations sur les données
Introduction
Dans ce Tutoriel, nous allons présenter la bibliothèque pandas. Nous allons passer en revue quelques informations essentielles sur cette bibliothèque et vous initier à l’analyse de données en utilisant les DataFrames pandas.
La bibliothèque pandas est un outil très important mis à la disposition des scientifiques et analystes de données travaillant en Python aujourd'hui. C’est une bibliothèque dédiée à la manipulation et l'analyse des données et sa structure de données clé est appelée DataFrame. Les DataFrames vous permettent de stocker et de manipuler des données tabulaires.
Passons à la pratique maintenant.
1. Création et chargement des données
Pandas est une bibliothèque facile à installer. Exécutez le script suivant dans un Jupyter notebook pour son installation :
Syntaxe:
!pip install pandas
Remarque : Si vous utilisez un autre IDE python, ouvrez votre programme de terminal (pour les utilisateurs de Mac) ou votre ligne de commande (pour les utilisateurs de Windows) et installez-le en utilisant l'une des commandes suivantes : conda install pandas ou pip install pandas.
Ensuite, il faut importer les bibliothèques avec lesquelles nous allons travailler. Importez pandas (nous l'importons généralement avec un nom plus court pd puisqu'il est très utilisé) et la bibliothèque numpy :
Syntaxe:
Import pandas as pd
Import numpy
Passons maintenant aux composantes de base de pandas.
1.1. Composantes essentielles de pandas : Series et DataFrames
Dans pandas, nous disposons de deux structures de données principales que nous pouvons explorer: Series et DataFrames. Quelle est donc la différence entre les deux ? Une DataFrame est un tableau bidimensionnel de valeurs avec un index de lignes et un index de colonnes. Par contre, une Serie est un tableau unidimensionnel de valeurs avec un seul index. Si la distinction entre les deux n'est pas encore claire, nous espérons que l'image ci-dessous vous aidera :
La création de ces deux structures de données est assez simple avec pandas.
Series :
Les Series et les DataFrames sont intimement liés. Il est utile de penser qu'une DataFrame n'est en fait qu'un ensemble de Series collées ensemble. Nous y reviendrons dans la prochaine section de ce tutoriel. Pour créer une Serie avec pandas nous utiliserons la commande pd.Series() :
Syntaxe:
S = pd.Series([1, 2, 3, 4, 5, 6, 7, 8])
print( S )
Résultat d’exécution:
D'autres paramètres peuvent être introduits dans la commande précédente, index pour indexer les lignes (permet de créer des étiquettes de lignes) et dtype pour préciser le type de données. Vous pouvez également utiliser la fonction head() qui affiche par défaut les 5 premières lignes de votre Series :
Syntaxe:
S = pd.Series([numpy.inf, 2, numpy.nan, 4, 5, 6, 7, 8], index=['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], dtype = float)
S.head()
Résultat d’exécution:
Remarquez que nous pouvons mettre la valeur numpy.nan (resp. numpy.inf) pour les valeurs non déterminées (resp. infinies).
DataFrames
Créer des DataFrames directement en Python est très utile. Il existe de nombreuses façons pour générer une DataFrame, nous présentons ici deux méthodes. La première option consiste à utiliser un simple dictionnaire, la deuxième un vecteur numpy.
Dans le script suivant, nous utilisons la commande pd.DataFrame() pour générer une DataFrame à partir d’un dictionnaire. C'est la façon standard de construire une nouvelle DataFrame. Nous utilisons le paramètres index vu précédemment avec des valeurs générées avec la fonction range() :
Syntaxe:
data = {
'Pays': ['Russie', 'Italie', 'Maroc', 'France'],
'Densité': [8.57, 200.27, 65.46, 117.63]
}
df = pd.DataFrame( data , index = range(1,5) )
df.head(3)
Résultat d’exécution:
Vous pouvez créer la même DataFrame en utilisant un vecteur numpy. Nous utiliserons le paramètre columns pour générer les noms des colonnes :
Syntaxe:
array = numpy.array( [['Russie', 8.57], ['Italie', 200.27], ['Maroc', 65.46], ['France', 117.63]] )
df = pd.DataFrame( array, index = range(1,5), columns = ['Pays','Densité'])
df.head(3)
Résultat d’exécution:
1.2. Lire des fichiers de données
Il est pratique de pouvoir créer une DataFrame ou une série avec pandans. Mais, la plupart du temps, nous ne créons pas nos propres données. Nous travaillons plutôt avec des données qui existent déjà. Les données peuvent être stockées sous différentes formats de fichier, le plus simple d'entre eux est le fichier CSV (Comma Separated Values). Lorsque vous ouvrez un fichier CSV (TEST.csv), vous obtenez un résultat qui ressemble à ceci :
Russie, 146716295, 17125402, 8.57
Italie, 60494785, 302072, 200.27
Maroc, 37481848, 846550, 65.46
France, 67063703, 551695, 117.63
Un fichier CSV est donc tout simplement un tableau de valeurs séparées par des virgules.
Nous utiliserons la fonction pd.read_csv() pour lire les données et générer une DataFrame. Cette fonction a plus de 30 paramètres optionnels que vous pouvez spécifier. Par exemple, le paramètre header = 0 suppose qu'il y a un header, et le paramètre index_col = None crée une nouvelle colonne pour l’index.
Syntaxe:
df = pd.read_csv('/tmp/TEST.csv', header = 0, index_col = None)
print( df )
Résultat d’exécution:
2. Quelques fonctions et propriétés utiles de pandas DataFrames
Il faut commencer par importer une table de données pour pouvoir la manipuler avec pandas. Dans ce tutoriel, nous utiliserons la bibliothèque pydataset. Installez-la avec la commande suivante :
Syntaxe:
!pip install pydataset
Importez le module data qui contient plusieurs tables de données. Dans ce tutoriel, nous utiliserons la table de données nommée movies. Vérifions qu’il s’agit bien d’une DataFrame pandas :
Syntaxe:
from pydataset import data
df_movies = data('movies')
print(type(df_movies))
Résultat d’exécution:
Créons une copie de notre DataFrame avec la fonction copy(), pour pouvoir la manipuler sans changer la table de données originale, et affichons ensuite les 5 premières lignes avec la fonction head() :
Syntaxe:
df_copy = df_movies.copy()
df_copy.head()
Résultat d’exécution:
2.1. DataFrames et indexation
En Python, nous pouvons accéder à l’attribut d'un objet en appelant objet.attribut. Les colonnes d'une DataFrame pandas fonctionnent à peu près de la même manière. Ainsi, pour accéder par exemple à la colonne rating et afficher les 5 première lignes le script et le suivant :
Syntaxe :
df_copy.rating.head()
Résultat d’exécution:
Nous pouvons aussi accéder à une colonne d’une DataFrame en utilisant l'opérateur d'indexation ([]) :
Syntaxe :
df_copy[ "rating" ].head()
Résultat d’exécution:
Ce sont les deux façons de sélectionner une colonne spécifique dans une DataFrame pandas. Cependant, l'opérateur d'indexation ([]) a l'avantage de pouvoir traiter les noms de colonnes contenant des caractères réservés.
Vous pouvez aussi accéder à un élément spécifique de chaque colonne en précisent sa position (l’indexation commence à partir de 1). Par exemple, pour accéder à la première valeur de la colonne rating, la commande est la suivante :
Syntaxe :
df_copy['rating'][1]
L'opérateur d'indexation est facile à utiliser car il fonctionne comme le reste de l'écosystème Python. Cependant, la bibliothèque pandas a ses propres fonctions d'accès aux données, loc et iloc. Pour des opérations plus avancées, ce sont ceux que vous êtes censés utiliser.
La fonction iloc est basée sur la position : elle consiste à sélectionner des données en fonction de leur position numérique. Par exemple, affichons les lignes de 5 jusqu’à 10 pour les deux colonnes rating (position 4) et votes (position 5) :
Syntaxe :
df_copy.iloc[ 4 : 10, 4 : 6 ]
Résultat d’exécution :
Remarquez que iloc utilise le schéma d'indexation Python, où le premier élément est inclus et le dernier exclu.
D’autre part, la fonction loc est basée sur les labels (index des lignes et noms des colonnes). Par exemple, affichons les lignes de 5 jusqu’à 10 pour les deux colonnes rating et votes :
Syntaxe :
df_copy.loc[ 5 : 10, ['rating', 'votes']]
Résultat d’exécution :
Nous avons vu comment sélectionner les colonnes et les lignes, mais que faire si nous voulons faire une sélection conditionnelle ? Par exemple, que faire si nous voulons filtrer nos films (DataFrame) pour ne montrer que les films ayant un rating supérieur ou égal à 8.0 ? Pour effectuer cette tâche, nous utilisons la fonction loc et nous lui appliquons la condition souhaitée. Voici un exemple :
Syntaxe :
df_copy.loc[ df_copy["rating"] >= 8.0 ].head()
Résultat d’exécution :
2.2. Générer de nouvelles colonnes
L'affectation des données à une DataFrame est facile. Vous pouvez créer une nouvelle colonne avec une valeur constante ou utiliser une ou plusieurs colonnes déjà existantes pour générer d’autres colonnes. Dans le script suivant, nous allons créer une nouvelle colonne que nous appelons Test :
Syntaxe:
df_copy['Test'] = 'test'
df_copy['Test'].head()
Résultat d’exécution:
Vous pouvez aussi utiliser une colonne déjà existante pour créer une autre. Ici, nous allons créer une nouvelle colonne contenant les valeurs de la colonne rating au carré :
Syntaxe :
df_copy['rating_square'] = [ x**2 for x in df_copy['rating'] ]
df_copy['rating_square'].head()
Résultat d’exécution:
Nous présentons une autre façon de faire à travers l’application la fonction apply() à la colonne que vous souhaitez utiliser pour générer une autre colonne. Supposons que vous voulez créer une nouvelle colonne nommée rating_bool qui contient des données de type string (Good si le rating > 5 sinon Bad), le script est le suivant :
Syntaxe :
df_copy['rating_bool'] = df_copy['rating'].apply(lambda x: 'good' if x > 5 else 'bad')
df_copy['rating_bool'].head()
Résultat d’exécution:
Affichons maintenant les trois nouvelles colonnes que nous avons créées :
Syntaxe :
df_copy.head()
Résultat d’exécution:
2.3. Obtenir des informations sur les données
Pandas offre de nombreuses fonctions qui restructurent les données de manière utile. Prenons par exemple la fonction info() qui devrait être l'une des toutes premières commandes que vous exécutez après le chargement de vos données :
Syntaxe :
df_copy.info()
Résultat d’exécution:
La fonction info() fournit les détails essentiels sur votre ensemble de données, telles que le nombre de lignes et de colonnes, le nombre de valeurs non nulles, le type de données dans chaque colonne et la quantité de mémoire utilisée par votre DataFrame. Remarquez que les colonnes budget et mpaa ont plusieurs valeurs manquantes.
Il y a aussi la fonction describe() qui génère un résumé statistique de la colonne donnée. Elle tient compte du type, ce qui signifie que sa sortie change en fonction du type de données (numérique ou non). Pour les données numériques (exécution sur la colonne rating) :
Syntaxe :
df_copy.rating.describe()
Résultat d’exécution:
Pour les données de type string (exécution sur la colonne title), voici ce que nous obtenons :
Syntaxe :
df_copy.title.describe()
Résultat d’exécution:
Pour générer une liste de valeurs uniques, nous pouvons utiliser la fonction unique() :
Syntaxe :
df_copy.rating_bool.unique()
Résultat d’exécution:
Pour générer une liste de valeurs uniques et leur fréquence dans l'ensemble de données, nous pouvons utiliser la méthode value_counts() :
Syntaxe :
df_copy.rating_bool.value_counts()
Résultat d’exécution:
2.4. Les valeurs manquantes
Les valeurs manquantes reçoivent la valeur NaN (Not a Number). Ces valeurs NaN sont toujours du type float64. Pandas fournit quelques fonctions spécifiques aux données manquantes. Pour sélectionner les valeurs manquantes, vous pouvez utiliser la fonction isnull() ou bien notnull(). Les deux fonctions renvoient une colonne de type boolien. Utilisons-la sur la colonne budget :
Syntaxe :
df_copy.budget.isnull()
Résultat d’exécution:
Vous pouvez utilisez la commande précédente comme argument pour la fonction loc() afin de générer une DataFrame ne contenant que les valeurs manquantes avec isnull() ou que les valeurs non manquantes avec notnull() :
Syntaxe:
df_copy.loc[df_copy.budget.isnull()].head()
Résultat d’exécution:
Pour remplacer les valeurs manquantes, pandas propose une fonction très pratique pour ce problème : fillna(). Par exemple, nous pouvons simplement remplacer chaque NaN par la moyenne de la colonne numérique (budget) obtenue en utilisant la fonction mean() :
Syntaxe:
mean = df_copy.budget.mean()
df_copy.budget.fillna(mean, inplace = True)
df_copy.budget.isnull().value_counts()
Résultat d’exécution:
2.5. Visualiser les données
Un autre avantage de la bibliothèque pandas est qu’elle permet de tracer directement des figures à partir des DataFrames et des séries. Pour les données catégorielles, utilisez les diagrammes à barres et les boxplots. Pour les données continues, utilisez des histogrammes, des graphiques linéaires et des boxplots.
Traçons la relation entre la colonne rating et votes en utilisant la fonction plot() avec le paramètre kind = 'scatter' :
Syntaxe:
df_copy.plot( kind = 'scatter', x = 'rating', y = 'votes')
Résultat d’exécution:
Si vous voulez tracer un histogramme simple basé sur une seule colonne, vous pouvez appeler la fonction plot() sur une colonne avec le paramètre kind = 'hist' :
Syntaxe:
df_copy.rating.plot( kind = 'hist')
Résultat d’exécution:
Finalement, en combinant des données catégorielles et continues, vous pouvez créer un boxplot regroupé par catégorie en utilisant la fonction boxplot():
Syntaxe:
df_copy.boxplot( column = 'rating', by = 'rating_bool')
Résultat d’exécution:
3. Exercices
3.1. Exercice 1
Question 1: Créer la DataFrame suivante :
Question 2: Créer une nouvelle colonne nommée Densité qui représente le nombre d’habitants par Km2 (Population / Superficie).
3.2. Exercice 2
Nous allons utiliser la table de données df_movies.
Question 1: Pour les trois colonnes suivantes : rating, budget, year, calculer le nombre de valeurs manquantes (True) et non manquantes (False) et afficher le résultat.
Question 2: Tracer un nuage de point « scatter » entre les deux colonnes rating et budget.
4. Solution des exercices
4.1. Exercice 1
Question 1:
Syntaxe:
import pandas as pd
import numpy as np
array = np.array( [['Russie', 146716295, 17125402],
['Italie', 60494785, 302072],
['Maroc', 37481848, 846550],
['France', 67063703, 551695]] )
df = pd.DataFrame( array, index = range(1,5), columns = ['Pays', 'Population', 'Superficie'])
df.head()
Résultat d’exécution:
Question 2:
Syntaxe:
df['Population'] = df['Population'].astype('int')
df['Superficie'] = df['Superficie'].astype('int')
df['Densité'] = round( df['Population']/df['Superficie'], 2)
df.head()
Résultat d’exécution:
4.2. Exercice 2
Question 1:
Syntaxe:
df_copy = df_movies.copy()
col_list = ['rating', 'budget', 'year']
for col in col_list:
print(df_copy[col].isnull().value_counts())
Résultat d’exécution:
Question 2:
Syntaxe:
df_copy.plot(kind = 'scatter', x = 'rating', y = 'budget');
Résultat d’exécution:
Conclusion
Nous sommes arrivés à la fin de ce tutoriel. J’espère qu’il vous sera utile à vous initier à l’analyse de données avec pandas. Mais ne vous arrêtez pas à ce stade. Ce tutoriel n’est qu’une brève introduction à la bibliothèque et à ses capacités, il existe encore énormément de notions à apprendre, foncez.
Merci d’avoir lu et bon courage pour la suite.