Pandas




Le package pandas sert à l’analyse de données, manipulées sous deux formats différents

  • les objets de la classe Series: une séquence uni-dimensionnelle comme, par exemple, un historique de cours
  • les objets de la classe DataFrame: tableau bi-dimensionnel, avec indexation des colonnes

Il est possible aussi d’indexer des données sur plusieurs niveaux en hiérarchisant ces niveaux: ce sera le rôle de l’objet MultiIndex.
Les tutoriels décrivant les membres et méthodes attachés à ces objets ne manquent pas. Le site https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html est un site de référence (certaines méthodes exposées sont un peu redondantes voire obsolètes).
On peut aussi utiliser la fonction help.
Par exemple, l’instructionhelp(pandas.Series) permet l’affichage détaillé dans l’interpréteur des attributs et méthodes de l’objet Series
Le plan adopté dans cette section sera logiquement

  1. Series
  2. DataFrame
  3. MultiIndex

Series

L’instruction qui crée une instance de Series s’écrit


L’objet data désigne les données que l’on veut convertir en Series.
Le format de ces données est très libre: il peut s’agir d’une séquence (liste, tuplet, chaîne de caractères, d’un dictionnaire, d’un itérateur, générateur, même objet Range, voire d’un objet Series lui-même).

Les arguments entre crochets sont facultatifs

  • index: mode d’indexation des valeurs. Par défaut, les données sont numérotées comme les éléments d’une séquence (0, 1, 2…): les indices sont affichées en colonne à gauche des données
  • dtype: par défaut, c’est le type donné implicitement aux valeurs de data
  • name: donne un nom à la série. Utile lorsque plusieurs objets Series sont regroupées pour former un objet DataFrame.
  • copy: effectue une copie d’une autre série (rôle identique à la fonction copy utilisée pour les listes et les dictionnaires)
  • fastpath: donnée interne à laquelle on ne touchera pas dans ce tutoriel (=False par défaut)

 
Exemples

 
Lorsque data est au format dict, les clés servent d’index

 
Pour créer une copie d’une série, on crée un autre objet qui récupère cette série comme data en assignant à l’argument nommé copy la valeur True.
Sans cet argument, la copie partage la même adresse que la série copiée.

 
Pour alléger le code, on peut créer une classe appelée serie qui héritera de pd.Series

 
L’instruction

x=pd.Series([0])

devient

x=serie([0])

DataFrame

Le constructeur d’un objet de type DataFrame peut recevoir les arguments suivants: data, index, columns, dtype et copy
Comme pour les objets de type Series, les arguments index, columns, dtype et copy (nommés), fournissent l’indexation, les en-têtes, le type des données et la copie éventuelle d’une autre instance de la classe DataFrame.
Les données (argument data), peuvent être de type Series, dictionnaire, liste, tuplet, voire DataFrame. Nous allons passer en revue les différents modes de création d’instance DataFrame en fonction du format de data.

Création à partir d’une liste

Création à partir d’un dictionnaire

Les titres des colonnes sont les clés du dictionnaire: donc les valeurs sont affichées en-dessous


 
Les valeurs du dictionnaire peuvent être aussi bien du type Series ou tuplets. Dans le cas des Series, l’indexation éventuelle choisie s’appliquera à tout le dataFrame.
A partir d’une liste de dictionnaires, on peut omettre certaines données, remplacées automatiquement par Nan

Création à partir d’une base SQL (voir chapitre Python et SQL)

Import d’une feuille Excel

La méthode read_excel de pandas permet de récupérer un fichier excel et d’extraire le contenu une feuille directement dans un objet dataFrame.
Ici, c’est la feuille ‘Quotes’ d’un fichier Historique.xlsm (historique de cours d’un panel de banques). La ligne séparant les en-têtes et les données étant vide, une ligne est remplie de NaN. On la supprime via la méthode drop. La syntaxe utilisée pour cette suppression tient compte de l’indexation temporelle, d’autres méthodes, ainsi que l’attribut iloc, étant présentés plus loin:
 

Conversion d’un dataFrame en dictionnaire

Pour créer un dictionnaire à partir d’un dataFrame avec en-têtes de colonnes servant de clés, on utilise la méthode to_dict(‘list’)
 

Conversion d’un dataFrame en liste

La conversion d’un dataFrame en liste, via la méthode to_dict(‘record’) entraîne que chaque ligne devient un dictionnaire
 

Ajout de colonnes

Par exemple, si la colonne doit s’appeler ‘statut’, on l’ajoute comme une clé de dictionnaire, les valeurs étant affichées en-dessous

Opérations arithmétiques sur les colonnes

Les opérations s’effectuent en utilisant les libellés des colonnes (clés).
Dans l’exemple qui suit, on ajoute une colonne à un tableau (objet DataFrame) affichant sur deux colonnes les dettes à court et moyen/long terme de quelques sociétés: les instructions créant une nouvelle colonne (appelée Passif à partir des trois autres est:

Statistiques sur les données

La méthode groupby regroupe les données relatives à un champ du tableau (colonne): à partir de là, on peut lancer des fonctions calculant des statistiques (moyenne mean(), std(), etc.)
Ici, on calcule l’âge moyen des musiciens en fonction de leur statut:
 

 
La méthode describe() permet d’afficher dans un même tableau les moyennes, écarts-types, min, max, etc. des colonnes remplies de valeurs numériques. Dans notre exemple, cela ne concerne que la colonne ‘Age’.
 

suppression de ligne

Dans le DataFrame précédent, on supprime la ligne 2 via la méthode drop. L’axe n° 0 désigne l’axe vertical, c’est à dire les indexes. Les crochets autour de 2 signifient que l’on pourrait augmenter dans une liste le nombre de lignes.
 

suppression de colonne

Dans l’exemple suivant, on supprime les colonnes ‘Age’ et ‘Statut’. Les intitulés de ces colonnes sont dans une liste passée en argument de la méthode drop, suivie de l’argument nommé axis=1 (la valeur 1 désigne l’axe horizontal).
 

 
Pour supprimer une seule colonne, les crochets sont facultatifs.

Ajout d’une ligne

L’attribut loc[n] identifie la ligne du dataFrame qui correspond à l’index n et non la ligne de rang n (quand l’indexation n’est pas celle adoptée par défaut). Donc, dans le cas où la première ligne du DataFrame a été supprimée, l’indexation commence par 1 et le dernier élément correspond à l’index len(df)+1

Filtre, sélections

Il est possible de sélectionner un segment de dataFrame, comme dans l’exemple ci-dessous
 

Comme pour les séquences, la dernière ligne (ligne 4) est non incluse.
Cette syntaxe est très limitée pour effectuer des filtrages plus fins. La sélection des lignes et colonnes s’effectue plutôt via les attributs loc et iloc.

  • loc: sélection en fonction du libellé d’une colonne ou d’une ligne
  • iloc: sélection en fonction du rang (ou index) de la colonne (resp.ligne)

Dans cette section, nous manipulons le tableau df affichant les données suivantes

Méthode loc

Syntaxe générale


les deux arguments passés à la méthode peuvent être

  • des segments: par exemple O:2 désigne les lignes 0 à 2 (2 inclus) du tableau
  • des listes ou tuplets: par exemple, [‘Nom’,’Age’] désigne les colonnes ‘Nom’ et ‘Age’
  • le symbole : désigne toutes les lignes (resp. colonnes)

Sélection des lignes 0 à 2 et des colonnes ‘Age’ et ‘Instrument’ (1), sélection des colonnes comprises entre ‘Age’ et ‘Statut’ (2)

Pour exclure une ou plusieurs colonnes de l’affichage

Pour filtrer les lignes, par exemple sélectionner les musiciens ‘pro’ en ne conservant que le prénom

Pour restreindre la recherche aux moins de 30 ans en spécifiant l’âge

Méthode iloc

Comme pour loc, les éléments passés peuvent être des valeurs, des segments, des listes ou le symbole :, à condition que ces éléments indiquent des positions (indexes) et non des données.
par exemple, pour afficher les 1ère et 3ème colonne


 
Lorsque des segments sont sélectionnés, que ce soit pour les lignes ou les colonnes, l’intervalle est ‘ouvert à droite’, c.a.d que la valeur supérieure est exclue, comme dans le cas de l’objet Range. Voir l’exemple ci-dessous

On peut sélectionner des lignes en fonction de leur position dans le tableau: la liste des numéros de ligne s’obtient via la méthode tolist() appliquée à la propriété index[:]

Par exemple, la sélection des lignes de numéros pairs s’écrit (ça ne sert à rien, mais juste pour l’exemple)

MultiIndex

Dans cette section, nous allons utiliser un ensemble de données plus conséquent que le précédent, qui contient les dépenses en fournitures de bureau d’une société par poste, service et date. Le dataFrame obtenu est appelé dep. Nous affichons les 25 premières lignes du tableau (qui en compte 120)
 

 

 
Chaque ligne d’un dataFrame est indéxée par une clé unique, la liste étant donnée par la propriété index
 

 
Pour changer la présentation en privilégiant certains champs et ordonner les valeurs en fonction de ces champs, on doit modifier l’indexation via la méthode set_index. Cette méthode prend en argument (en première position, car c’est un argument positionnel) la liste des champs à privilégier en partant du champ principal. Cette méthode permet de modifier l’affichage sans affecter le dataFrame de manière permanente. Pour obtenir un changement permanent, on affecte à l’argument nommé inplace (en dernière position donc) la valeur True.
 

 
Même chose, mais en créant une copie du dataFrame appelée dep2 et en modifiant l’indexation de façon permanente
 

 
L’objet RangeIndex initial est remplacé par un MultiIndex
 

 
On remarque qu’à la date du 18/02/2018, les dépenses en téléphone du service RH figurent sur deux lignes, ce qui ne convient pas quand on veut une présentation où les données apparaissent groupées.
Pour éviter cela, on revient au DataFrame initial, dont les lignes de type ndarray sont d’abord converties en listes et ces listes sont regroupées quand leurs trois premiers éléments (DATES, POSTES et SERVICE) sont identiques. Le code suivant affiche les 10 premières lignes du DataFrame ainsi transformé
 

 

 
Les tableaux multiindexés restent des objets DataFrame avec des méthodes loc et iloc qui s’appliquent aussi, la première colonne, ici ‘DATES’, jouant le rôle d’index. La première coordonnée passée à loc doit donc être une date.
 

 
Si l’on souhaite une présentation de préférence par poste, on « swappe » les dates et les postes
&nbsp:

 

 
La méthode groupby s’utilise de la même façon
 

 
Le format des dates récupérées ne permet pas de segmenter les dépenses en périodes. Le code suivant transforme les données de la forme dd/mm/yyyy (type str) en valeurs de type datetime.date au format yyyy-mm-dd en supprimant les 0 intempestifs.
 

 
On peut maintenant restreindre la plage des dates de dépenses par exemple aux dates antérieures au 15/03/2018 (2018-3-15):