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:

Écrire un programme Hadoop MapReduce en Python

Cet article va vous présenter comment écrire un programme MapReduce Hadoop en utilisant le langage de programmation Python.

Hadoop est développé en Java et permet d’écrire des programmes map/reduce en Java. Mais il est tout à fait possible d’écrire des applications MapReduce dans d’autres langages en utilisant l’API Hadoop Streaming. Cette API prend en charge tous les langages qui peuvent lire à partir de l’entrée standard et écrire sur la sortie standard.

Prérequis

Il est nécessaire d’avoir une installation d’Apache Hadoop. Si besoin , vous pouvez consulter notre article sur comment installer Hadoop sur une machine Ubuntu. Pour pouvoir reproduire l’exemple présenté, pensez à démarrer votre serveur HDFS et Yarn.

Nous allons également devoir manipuler des fichiers sur le serveur HDFS. Les commandes à exécuter seront données. Toutefois, vous pouvez consulter l’article Manipuler vos fichiers sur HDFS en ligne de commandes pour en savoir plus.

Nous allons utiliser des scripts python exécutables pour définir le mapper et le reducer. Vous devrez renseigner en tête de chaque script Python le chemin vers l’interpréteur python de la forme: #!/usr/bin/python3 (à personnaliser suivant l’interpréteur Python que vous souhaitez utiliser).

Description du problème à résoudre

Nous allons reprendre le problème classique de comptage du nombre d’occurrences des mots dans des fichiers textes. Le programme reçoit en entrée des fichiers textes. L’étape du map permet d’associer à chaque terme le nombre 1. En sortie de l’étape de reduce, un fichier texte est produit et contiendra sur chaque ligne un mot et le nombre d’occurrences de ce mot séparé par une tabulation.

Schéma de calcul du comptage en MapReduce

Programme MapReduce écrit en Python

Nous allons présenter les deux scripts qui vont servir de mapper et de reducer pour l’application MapReduce que nous cherchons à mettre en place. Les deux scripts seront sauvegardés dans /home/hdoop/Documents/hadoop-stremaing/

Etape de Map

Copiez et sauvegardez ce code dans un script mapper.py. Ce script lit à partir de l’entrée standard STDIN (commande sys.stdin) les données. Chaque ligne va être divisée en mot et retournée sous forme de tuple sur la sortie standard STDOUT. Chaque tuple sera de la forme « <mot> 1 ». Il s’agit évidemment d’un comptage intermédiaire étant donné qu’un mot peut être répété plus d’une fois. Le comptage final par mot sera calculé par le reducer dans l’étape suivante.

#!/usr/bin/python3.10

import re
import sys

for line in sys.stdin:
    # suppression des espaces en début et fin de ligne
    line = line.strip()

    # suppression de la ponctuation et mise en minuscule
    line = re.sub(r"[^\w\s]", ' ', line.lower())

    # division des lignes en mots
    words = line.split()

    for word in words:
        # écriture des résultats en STDOUT avec des tabulations en délimiteur
        print(f"{word.lower()} \t 1")

Etape de Reduce

Copiez et sauvegardez ce code dans un script reducer.py. Ce script lit à partir de l’entrée standard STDIN les sorties du script mapper.py. Les occurrences de chaque mot sont agrégées et écrites sur la sortie standard STDOUT.

#!/usr/bin/python3

import sys
current_word = None
current_count = 0
word = None

# lecture depuis l'entrée standard STDIN
for line in sys.stdin:
    # suppression des espaces en début et fin de ligne
    line = line.strip()

    # divise une chaîne de caractère issus du mapper.py
    # en une liste sur la tabulation
    word, count = line.split('\t', 1)

    # convertit la variable count en entier (string initialement)
    try:
        count = int(count)
    except ValueError:
        # si count n'est pas un nombre, on ignore la ligne
        continue

    # trie la sortie de mapperpy par Hadoop par mot
    # avant d'être traité par le reducer
    if current_word == word:
        current_count += count
    else:
        if current_word:
            # écriture du résultat sur la sortie standard STDOUT
            print(f"{current_word}\t{current_count}")
        current_count = count
        current_word = word

# écriture du résultat du dernier mot sur la sortie
# standard STDOUT si besoin
if current_word == word:
    print(f"{current_word}\t{current_count}")

Tester son code en local

Avant d’utiliser Hadoop Streaming, il est conseillé tester ces deux scripts Python. Au préalable, il faut changer les permissions de ces deux fichiers en donnant à l’utilisateur l’autorisation de les exécuter:

chmod u+x mapper.py

chmod u+x reducer.py

Nous allons commencer par tester le mapper en utilisant une phrase simple de test: « Hadoop et Python ensemble. Lancement de scripts Python ». Entrez la commande suivante dans un terminal:

echo "Hadoop et Python ensemble. Lancement Script Python" | ./mapper.py
Test du script mapper.py en ligne de commande

On retrouve le résultat attendu: chaque mot est associé à la valeur 1. Le mot « Python » étant répété deux fois dans la phrase de test et il apparaît donc deux fois dans le résultat sous la forme: « python 1 ».

Enfin pour reproduire le comportement de Hadoop en streaming, nous pouvons tester le processus de MapReduce avec la commande suivante:

echo "Hadoop et Python ensemble. Lancement Script Python" | ./mapper.py | sort -k1,1 | ./reducer.py
Test des scripts mapper.py et reducer.py en ligne de commande

On retrouve dans ce cas pour chaque mot, son nombre d’occurrence dans la phrase simple qui a été testée. Le mot « Python » apparaît dans le résultat final sour la forme « python 2 » car il apparaît deux fois.

Exécuter un job Streaming MapReduce

Dans cette section, nous allons décrire les étapes pour exécuter un exemple complet en utilisant Hadoop Streaming.

Télécharger les données d’entrée

Pour réaliser un test plus complet, nous proposons d’utiliser des livres mis à disposition gratuitement par le projet Gutenberg:

Utilisez chaque lien pour télécharger la version texte au format Plain Text UTF-8.

Copier les données d’entrée sur HDFS

Les données à traiter avec Hadoop Streaming doivent être placé sur HDFS. Pour cela, vous devez les copier depuis votre local sur HDFS en utilisant la commande « hdfs dfs -copyFromLocal » de la façon suivante:

Copie des fichiers tests sur HDFS

Dans cet exemple, les répertoires sont définis comme :

  • en local: « /home/hdoop/Documents/data/gutenberg« . Répertoire dans lequel les fichiers du projet Gutenberg ont été sauvegardés.
  • sur HDFS: « /user/hdoop/gutenberg« . Répertoire sur HDFS dans lequel les fichiers sont copiés.

Exécuter le processus avec Hadoop MapReduce

Depuis le répertoire dans lequel vous avez sauvegardé les scripts mapper.py et reducer.py, nous allons lancer la commande Hadoop pour exécuter ce job en streaming MapReduce. Dans un terminal, tapez la commande suivante:

hadoop jar /usr/local/hadoop-3.3.3/share/hadoop/tools/lib/hadoop-streaming-3.3.3.jar \
  -file mapper.py  -mapper mapper.py \
  -file reducer.py  -reducer reducer.py \
  -input /user/hdoop/gutenberg/* \
  -output /user/hdoop/gutenberg-output

Vous pouvez voir ici que nous avons utilisé le jar hadoop-streaming-3.3.3 qui correspond à celui de la version d’Hadoop 3.3.3. Modifiez-le en fonction de la version de Hadoop installée sur votre machine si différente.

Les options de bases utilisées pour cette commande sont les suivantes:

OptionDescription
-mappercommande à exécuter pour le map
-reducercommande à exécuter pour le reduce
-inputle path sur HDFS contenant les données d’entrée du mapper
-outputle path HDFS pour l’écriture des résultats du reducer
-filechemin des exécutables en local mis à disposition des nœuds de calculs
Options de la commande Hadoop MapReduce
Exécution d’un processus MapReduce avec Hadoop Streaming

Une fois le processus Hadoop lancé, il est possible de le monitorer depuis l’interface http://localhost:8088/. Elle donne plusieurs informations comme le détail des processus en cours, terminé en succès ou en échec et un ensemble d’information utile pour monitorer vos calculs.

Monitoring des processus MapReduce depuis l’interface web

Conclusion

Félicitations, vous avez dorénavant les connaissances nécessaire pour développer vos programmes MapReduce en Python. Et vous savez comment comment les exécuter en utilisant l’API Hadoop Streaming.

Sur le même sujet: Consulter l’article Installer Hadoop sur Ubuntu

Pour aller plus loin: Consulter l’article Requêter avec HiveQL

Référence

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