Python Pandas – Comptage des valeurs uniques d’une Series

En Python, la librairie Pandas est incontournable pour les ingénieurs en données. Cette librairie offre un cadre simple et efficace pour transformer, manipuler et traiter les données.

Parmi les opérations usuelles, celle de compter les valeurs uniques dans une Series Pandas et de déterminer leur fréquence. La librairie Pandas offre la fonction value_counts() pour faire ce comptage de valeurs uniques dans une Series. Le comptage peut retourner le nombre de chaque valeur de façon absolue, de façon relative ou encore par intervalle. La prise en compte des valeurs Null est contrôlable ainsi que le tri par valeurs du résultats de ces comptages.

Nous allons aborder et illustrer les différentes options offertes par cette méthode dans cet article.

Cet article fait parti d’un ensemble d’article sur les utilisations avancées en Pandas.

Syntaxe générale

La syntaxe générale de la méthode value_counts() appliquée sur une Series Pandas se présente sous la forme :

Series.value_counts(normalize=False, 
                    sort=True, 
                    ascending=False, 
                    bins=None, 
                    dropna=True)

La description des paramètres est la suivante :

ParamètreDescriptionValeur par défaut
normalizeRetourne la valeur relative de chaque valeur uniqueFalse
sortTri selon la fréquence de la valeurTrue
ascendingTri selon l’ordre croissantFalse
binsCalcul la fréquence de valeur par intervalleoptionnel
dropnaPermet d’exclure les valeurs NaNTrue
Description des paramètres de la méthode value_counts()

Données Tests

Pour illustrer cette article, nous allons construire un DataFrame. Ce DataFrame est constitué des notes de 1 à 5 données pour certaines villes. Voici comment construire ce DataFrame utilisé pour montrer l’utilisation des différentes options de la méthode value_counts() :

import random
import pandas as pd

villes = ['Paris']*3 + ['New York']*5 + ['Montreal']*10 + [pd.NA]*4 + ['Milan']*1

notes = [random.randint(1, 5) for i in range(villes.size)]

df = pd.DataFrame({'Ville': villes, 'Note': notes})

Ce DataFrame est constitué de 23 lignes dont voici les 5 premières lignes :

| Ville    |   Note |
|----------|--------|
| Paris    |      4 |
| Paris    |      5 |
| Paris    |      1 |
| New York |      3 |
| New York |      2 |

Utilisation des valeurs par défaut

Dans cet exemple, nous allons compter la fréquence d’apparition de chaque élément unique dans la colonne ‘Ville’. Utilisons la méthode value_counts() sans préciser de paramètres et donc utiliser leur valeur par défauts :

print(df['Ville'].value_counts())

Le résultat de la méthode value_counts() est une Series Pandas avec comme index les éléments uniques de la Series sur laquelle la méthode a été appliquée :

Montreal    10
New York     5
Paris        3
Milan        1
dtype: int64

Ainsi en utilisant l’index, il est possible d’accéder à la fréquence d’un élément de la façon suivante :

# Fréquence de la valeur 'Montreal'
print(f"Fréquence de la ville de Montréal : {df['Ville'].value_counts()['Montreal']}")

Dans ce cas, la fréquence de la ville de « Montréal » est renvoyée :

Fréquence de la ville de Montréal : 10

Tri sur les fréquences et l’index

Il est possible de trier le résultat en utilisant les paramètres sort et ascending qui par défaut ont les valeurs True et False. Il suffit de jouer avec ces deux paramètres pour changer la façon dont le résultat sera trié. Par exemple, pour trier dans l’ordre croissant des fréquences des éléments dans la Series, il faut mettre le paramètre ascending à True de la façon suivante :

print(df['Ville'].value_counts(ascending=True))
Milan        1
Paris        3
New York     5
Montreal    10
Name: Ville, dtype: int64

Nous voyons que dorénavant les villes sont triées dans l’ordre croissant de leur fréquences.

Nous avons vu que la méthode value_counts() permet de trier le résultat du comptage sur une Series. Il est également intéressant de vouloir trier le résultat selon l’ordre de l’index du résultat de la méthode value_counts(). Pour cela, il faut appliquer la méthode sort_index() sur le résultat. Par exemple, si nous souhaitons trier le résultat par ordre croissant du nom de la ville :

print(df['Ville'].value_counts().sort_index(ascending=True))
Milan        1
Montreal    10
New York     5
Paris        3
Name: Ville, dtype: int64

Nous voyons que cette fois le résultat est bien trié selon l’ordre alphabétique croissant de l’index du résultat.

Calcul des fréquences en pourcentage

Jusqu’à présent, nous avons vu comment il est possible de calculer les fréquences de chaque élément d’une Series. Avec le paramètre normalize, il est également possible d’obtenir les fréquences en pourcentage. Pour cela, il faut mettre la valeur de ce paramètre à True comme ceci :

print(villes.value_counts(normalize=True))
Montreal    0.526316
New York    0.263158
Paris       0.157895
Milan       0.052632
Name: Ville, dtype: float64

Nous obtenons donc la proportion de chaque élément de la Series. Ainsi la ville de « Montreal » apparaît 52.6% fois dans la colonne ‘Ville’.

Gestion des valeurs manquantes

Dans la colonne ‘Ville’, il y a quatre valeurs manquantes (valeur NaN). Par défaut, la méthode value_counts() exclue les valeurs manquantes du résultat (paramètre dropna=True par défaut). Ainsi pour tenir compte de ces valeurs manquantes, il faudra modifier le paramètre dropna à False :

print(df['Ville'].value_counts(dropna=False))
Montreal    10
New York     5
<NA>         4
Paris        3
Milan        1
dtype: int64

Cette fois-ci, le résultat contient comme attendu le nombre de valeurs manquantes (<NA>) : 4 dans le cas présent.

Calcul de fréquence par intervalles

Enfin, il est possible de calculer les fréquences par intervalles en utilisant le paramètre bins pour préciser le nombre d’intervalle souhaité. L’utilisation de ce paramètre est limitée au Series numérique. Donc pour illustrer ce point, nous allons utiliser la colonne ‘Note’ et la subdiviser en cinq intervalles de la façon suivante :

print(df['Note'].value_counts(bins=5))
(1.8, 2.6]      6
(0.995, 1.8]    5
(3.4, 4.2]      5
(4.2, 5.0]      4
(2.6, 3.4]      3
Name: Note, dtype: int64

Nous avons ici les fréquences des valeurs sur les intervalles donnés en index.

Représentation graphique

Un dernier point concerne la représentation graphique des fréquences d’une Series. La libraire Pandas permet d’avoir rapidement un aperçu sous forme graphique du résultat de la méthode value_counts() en appliquant la méthode plot() sur le résultat. Voici un exemple d’une représentation sous forme de bar de la fréquence de chaque ville :

df['Ville'].value_counts().plot(kind='barh', 
                                title='Fréquence par ville') ; 
Plot des fréquences calculées avec la méthode value_counts()

Conclusion

Nous avons vu dans cet article l’ensemble des possibilités offertes par la méthode value_counts() de la librairie Pandas pour :

  • Calculer des fréquences en valeur absolue ou en pourcentage,
  • Trier par fréquence ou par valeur unique,
  • Gérer les valeurs manquantes,
  • Calculer le nombre de valeur par intervalles,
  • Représenter les résultats sous forme graphique.

Référence

Python Pandas – Trois façons de filtrer vos DataFrame

Introduction

La librairie Python Pandas est sans aucun doute parmi les plus utiliser pour manipuler et transformer vos données. La librairie Pandas fait partie des librairies fondamentales pour les ingénieurs de données. Elle offrent des outils puissants pour manipuler vos données.

Filtrer les lignes d’un DataFrame est une des opérations les plus courantes. Cette opération consiste à sélectionner les lignes d’un DataFrame sur la base de critères spécifiques.

Dans cet article, nous allons discuter de trois façons de filtrer les données d’un DataFrame en utilisant les valeurs d’une colonne.

Jeu de Données

Pour cet article, on vous propose de construire un jeu de données qui sera utilisé pour les illustrations des différentes méthodes pour filtrer un DataFrame.

import pandas as pd

df = pd.DataFrame({'id': [1, 2, 3, 4, 5, 6],
                   'nom': ['Pierre', 'Paul', 'Emma', 'Lisa', 'John', 'Eve'],
                   'salaire': [20000, 25000, 30000, 24000, 35000, 21000]})

Aperçu du jeu de données utilisé dans cet article :

+----+------+--------+-----------+
|    |   id | nom    |   salaire |
|----+------+--------+-----------|
|  0 |    1 | Pierre |     20000 |
|  1 |    2 | Paul   |     25000 |
|  2 |    3 | Emma   |     30000 |
|  3 |    4 | Lisa   |     24000 |
|  4 |    5 | John   |     35000 |
|  5 |    6 | Eve    |     21000 |
+----+------+--------+-----------+

Notre objectif est de filtrer les lignes sur les salaires strictement supérieur à 20 000 € et inférieur ou égale à 25 000€ (20000 < salaire <= 25000). Vous pourrez vérifier par la suite que les lignes répondant à cette condition sont les suivantes :

+----+------+-------+-----------+
|    |   id | nom   |   salaire |
|----+------+-------+-----------|
|  1 |    2 | Paul  |     25000 |
|  3 |    4 | Lisa  |     24000 |
|  5 |    6 | Eve   |     21000 |
+----+------+-------+-----------+

Opérateurs Logiques

La première de ces approches consiste à utiliser les opérateurs logiques. Ces opérateurs disponibles dans Pandas permettent d’appliquer des opérations de logiques sur les Series et de chaîner les conditions ensemble. La condition qui en résulte est alors appliquée sur le DataFrame à filtrer.

Pour filtrer le DataFrame df sur les salaires, on peut écrire l’instruction suivante:

df[(df['salaire'] > 20000) & (df['salaire'] <= 25000)]

Les deux conditions sur les bornes du salaire sont écrites avec les opérateurs de comparaisons (< et <=) et groupées entre des parenthèses. Les conditions sur la borne inférieur et supérieur du salaire sont liées par l’opérateur & (and).

Consulter la documentation officielle pour une présentation détaillée du filtrage s’appuyant sur les opérateurs logiques et l’algèbre booléenne.

DataFrame – Méthode query()

La méthode query() permet de requêter directement sur le DataFrame. La syntaxe générale de cette méthode est la suivante :

dataframe.query(expression, inplace)

Les paramètres sont les suivants :

ParamètresValeursDescription
expressionRequis. Requête sous forme de string à appliquer
inplaceTrue | FalseOptionnel. Booléen qui permet d’indiquer si l’on souhaite modifier le DataFrame original (True) ou retourner une copie (False) – Par défaut: False
Paramètres de la méthode query()

Dans l’exemple traité dans cet article, le filtre sur les salaires s’écrit comme:

df.query("salaire > 20000 & salaire <= 25000")

On voit que la condition sur les salaire est représenté par la string : "salaire > 20000 & salaire <= 25000". Cette condition est similaire à celle utilisée précédemment tout en rendant la lecture du code plus lisible.

Consultez la documentation officielle sur la méthode query() pour une présentation détaillée.

Series – Méthode between()

La méthode between() va s’appliquer sur la Series sur laquelle on souhaite appliquer un filtre. Et c’est le résultat sur la Series que l’on va appliquer sur le Datarame pour le filtrer. La syntaxe générale de cette méthode est la suivante :

series.between(left, right, inclusive)
ParamètreValeurDescription
leftBorne de gauche
rightBorne de droite
inclusiveboth | neither | left | rightIndique si les bornes de gauche et/ou de droite sont incluses (‘both’ par défaut)
Paramètre de la méthode between()

Dans l’exemple traité dans cet article, le filtre sur les salaires s’écrit alors comme:

df[df['salaire'].between(20000, 25000, inclusive='right')]

Dans cet exemple, le paramètre inclusive a été mis à ‘right‘ car seule la borne de droite doit être incluse. On voit ici que le filtre est fait sur la colonne ‘salaire‘ (df['salaire']) contrairement à la méthode query() qui s’applique directement sur le DataFrame.

Consultez la documentation officielle sur la méthode between() pour une présentation détaillée.

Conclusion

Nous avons présenté trois méthodes pour filtrer un DataFrame Pandas en se basant sur les valeurs d’une colonne. Les trois méthodes pour filtrer les lignes d’un DataFrame df sont résumées ici :

VersionCode
Opérateurs logiquesdf[(df['salaire'] > 20000) & (df['salaire'] <= 25000)]
Méthode query()df.query("salaire > 20000 & salaire <= 25000")
Méthode between()df[df['salaire'].between(20000, 25000, inclusive='right')]
Trois façons de faire le même filtre sur un DataFrame Python

Les trois méthodes conduisent aux mêmes résultats. La raison qui conduit à utiliser une méthode plutôt qu’une autre est d’améliorer la lisibilité de votre code Python. Et pour cela, les méthodes query() et between() sont à privilégier.

Référence

Les références ayant servi à la rédaction de cet article: