Introduction
Dans ce laboratoire, vous apprendrez à utiliser les générateurs Python pour construire des pipelines de traitement de données efficaces. Les générateurs sont une fonctionnalité puissante de Python qui permet de produire des données à la demande, éliminant ainsi le besoin de stocker toutes les données en mémoire en même temps. Vous découvrirez comment connecter des générateurs pour créer des flux de travail de traitement de données similaires aux pipes Unix.
Les objectifs de ce laboratoire sont de comprendre les bases des pipelines de traitement basés sur les générateurs, de créer des flux de travail de traitement de données à l'aide de générateurs Python, et de filtrer et de formater des flux de données en temps réel. Le fichier ticker.py sera créé au cours de ce laboratoire. Notez que pour cet exercice, le programme stocksim.py doit être en cours d'exécution en arrière-plan, et vous utiliserez la fonction follow() d'un exercice précédent.
Pipeline de générateurs de base avec des données CSV
Dans cette étape, nous allons apprendre à créer un pipeline de traitement de base en utilisant des générateurs. Mais d'abord, comprenons ce que sont les générateurs. Les générateurs sont un type spécial d'itérateur en Python. Contrairement aux itérateurs normaux qui peuvent charger toutes les données en mémoire d'un coup, les générateurs produisent des valeurs à la demande. Cela est extrêmement utile lorsqu'il s'agit de traiter de grands flux de données car cela économise de la mémoire. Au lieu de devoir stocker l'ensemble du jeu de données en mémoire, le générateur produit des valeurs une par une au fur et à mesure que vous en avez besoin.
Comprendre les générateurs
Un générateur est essentiellement une fonction qui renvoie un itérateur. Lorsque vous itérez sur cet itérateur, il produit une séquence de valeurs. La façon d'écrire une fonction générateur est similaire à celle d'une fonction normale, mais il y a une différence clé. Au lieu d'utiliser l'instruction return, une fonction générateur utilise l'instruction yield. L'instruction yield a un comportement unique. Elle met en pause la fonction et enregistre son état actuel. Lorsque la valeur suivante est demandée, la fonction reprend là où elle s'était arrêtée. Cela permet au générateur de produire des valeurs de manière incrémentielle sans avoir à recommencer depuis le début à chaque fois.
Utilisation de la fonction follow()
La fonction follow() que vous avez créée précédemment fonctionne de manière similaire à la commande Unix tail -f. La commande tail -f surveille en continu un fichier pour détecter de nouveaux contenus, tout comme la fonction follow(). Maintenant, utilisons - la pour créer un simple pipeline de traitement.
Étape 1 : Ouvrir une nouvelle fenêtre de terminal
Tout d'abord, ouvrez une nouvelle fenêtre de terminal dans le WebIDE. Vous pouvez le faire en allant dans Terminal → New Terminal. Cette nouvelle fenêtre de terminal sera là où nous exécuterons nos commandes Python.
Étape 2 : Démarrer un shell interactif Python
Une fois que la nouvelle fenêtre de terminal est ouverte, démarrez un shell interactif Python. Vous pouvez le faire en entrant la commande suivante dans le terminal :
python3
Le shell interactif Python vous permet d'exécuter du code Python ligne par ligne et de voir immédiatement les résultats.
Étape 3 : Importer la fonction follow et configurer le pipeline
Maintenant, nous allons importer la fonction follow et configurer un pipeline de base pour lire les données des actions. Dans le shell interactif Python, entrez le code suivant :
>>> from follow import follow
>>> import csv
>>> lines = follow('stocklog.csv')
>>> rows = csv.reader(lines)
>>> for row in rows:
... print(row)
...
Voici ce que chaque ligne fait :
from follow import follow: Cela importe la fonctionfollowdu modulefollow.import csv: Cela importe le modulecsv, qui est utilisé pour lire et écrire des fichiers CSV en Python.lines = follow('stocklog.csv'): Cela appelle la fonctionfollowavec le nom de fichierstocklog.csv. La fonctionfollowrenvoie un générateur qui produit de nouvelles lignes au fur et à mesure qu'elles sont ajoutées au fichier.rows = csv.reader(lines): La fonctioncsv.reader()prend les lignes générées par la fonctionfollowet les analyse en lignes de données CSV.- La boucle
foritère à travers ces lignes et les affiche une par une.
Étape 4 : Vérifier la sortie
Après avoir exécuté le code, vous devriez voir une sortie similaire à ceci (vos données varieront) :
['BA', '98.35', '6/11/2007', '09:41.07', '0.16', '98.25', '98.35', '98.31', '158148']
['AA', '39.63', '6/11/2007', '09:41.07', '-0.03', '39.67', '39.63', '39.31', '270224']
['XOM', '82.45', '6/11/2007', '09:41.07', '-0.23', '82.68', '82.64', '82.41', '748062']
['PG', '62.95', '6/11/2007', '09:41.08', '-0.12', '62.80', '62.97', '62.61', '454327']
...
Cette sortie indique que vous avez créé avec succès un pipeline de données. La fonction follow() génère des lignes à partir du fichier, et ces lignes sont ensuite transmises à la fonction csv.reader(), qui les analyse en lignes de données.
Si vous avez vu assez de résultats, vous pouvez arrêter l'exécution en appuyant sur Ctrl+C.
Qu'est - ce qui se passe ?
Décortiquons ce qui se passe dans ce pipeline :
follow('stocklog.csv')crée un générateur. Ce générateur suit le fichierstocklog.csvet produit de nouvelles lignes au fur et à mesure qu'elles sont ajoutées au fichier.csv.reader(lines)prend les lignes générées par la fonctionfollowet les analyse en données de ligne CSV. Il comprend la structure des fichiers CSV et divise les lignes en valeurs individuelles.- La boucle
foritère ensuite à travers ces lignes, les affichant une par une. Cela vous permet de voir les données dans un format lisible.
Ceci est un exemple simple d'un pipeline de traitement de données utilisant des générateurs. Dans les étapes suivantes, nous allons construire des pipelines plus complexes et utiles.
Création de la classe Ticker
Dans le traitement de données, travailler avec des données brutes peut être assez difficile. Pour organiser et optimiser notre travail avec les données d'actions, nous allons définir une classe appropriée pour représenter les cours d'actions. Cette classe servira de modèle pour nos données d'actions, rendant notre pipeline de traitement de données plus robuste et plus facile à gérer.
Création du fichier ticker.py
Tout d'abord, nous devons créer un nouveau fichier dans le WebIDE. Vous pouvez le faire en cliquant sur l'icône "New File" ou en cliquant avec le bouton droit dans l'explorateur de fichiers et en sélectionnant "New File". Nommez ce fichier
ticker.py. Ce fichier contiendra le code de notre classeTicker.Maintenant, ajoutons le code suivant à votre fichier
ticker.pynouvellement créé. Ce code définira notre classeTickeret configurera un simple pipeline de traitement pour la tester.
## ticker.py
from structure import Structure, String, Float, Integer
class Ticker(Structure):
name = String()
price = Float()
date = String()
time = String()
change = Float()
open = Float()
high = Float()
low = Float()
volume = Integer()
if __name__ == '__main__':
from follow import follow
import csv
lines = follow('stocklog.csv')
rows = csv.reader(lines)
records = (Ticker.from_row(row) for row in rows)
for record in records:
print(record)
- Après avoir ajouté le code, enregistrez le fichier. Vous pouvez le faire en appuyant sur
Ctrl+Sou en sélectionnant "File" → "Save" dans le menu. Enregistrer le fichier garantit que vos modifications sont conservées et peuvent être exécutées plus tard.
Compréhension du code
Examinons de plus près ce que ce code fait étape par étape :
Au début du code, nous importons
Structureet les types de champs du modulestructure.py. Ce module a déjà été configuré pour vous. Ces importations sont essentielles car elles fournissent les éléments de base pour notre classeTicker. La classeStructuresera la classe de base de notre classeTicker, et les types de champs commeString,FloatetIntegerdéfiniront les types de données de nos champs de données d'actions.Ensuite, nous définissons une classe
Tickerqui hérite deStructure. Cette classe a plusieurs champs qui représentent différents aspects des données d'actions :name: Ce champ stocke le symbole de l'action, comme "IBM" ou "AAPL". Il nous aide à identifier de quelle société d'actions nous traitons.price: Il contient le prix actuel de l'action. C'est une information cruciale pour les investisseurs.dateettime: Ces champs nous indiquent quand le cours de l'action a été généré. Savoir l'heure et la date est important pour analyser les tendances des prix des actions au fil du temps.change: Cela représente la variation du prix de l'action. Il montre si le prix de l'action a augmenté ou diminué par rapport à un point précédent.open,high,low: Ces champs représentent le prix d'ouverture, le prix le plus élevé et le prix le plus bas de l'action pendant une certaine période. Ils nous donnent une idée de la fourchette de prix de l'action.volume: Ce champ stocke le nombre d'actions échangées. Un volume d'échange élevé peut indiquer un fort intérêt du marché pour une action particulière.
Dans le bloc
if __name__ == '__main__':, nous configurons un pipeline de traitement. Ce bloc de code sera exécuté lorsque nous exécutons directement le fichierticker.py.follow('stocklog.csv')est une fonction qui génère des lignes à partir du fichierstocklog.csv. Elle nous permet de lire le fichier ligne par ligne.csv.reader(lines)prend ces lignes et les analyse en données de ligne. CSV (Comma - Separated Values) est un format de fichier courant pour stocker des données tabulaires, et cette fonction nous aide à extraire les données de chaque ligne.(Ticker.from_row(row) for row in rows)est une expression générateur. Elle prend chaque ligne de données et la convertit en un objetTicker. De cette façon, nous transformons les données CSV brutes en objets structurés plus faciles à manipuler.- La boucle
foritère sur ces objetsTickeret les affiche un par un. Cela nous permet de voir les données structurées en action.
Exécution du code
Exécutons le code pour voir comment il fonctionne :
Tout d'abord, nous devons nous assurer que nous sommes dans le répertoire du projet dans le terminal. Si vous n'y êtes pas déjà, utilisez la commande suivante pour y accéder :
cd /home/labex/projectUne fois que vous êtes dans le bon répertoire, exécutez le script
ticker.pyen utilisant la commande suivante :python3 ticker.pyAprès avoir exécuté le script, vous devriez voir une sortie similaire à ceci (vos données varieront) :
Ticker(IBM, 103.53, 6/11/2007, 09:53.59, 0.46, 102.87, 103.53, 102.77, 541633) Ticker(MSFT, 30.21, 6/11/2007, 09:54.01, 0.16, 30.05, 30.21, 29.95, 7562516) Ticker(AA, 40.01, 6/11/2007, 09:54.01, 0.35, 39.67, 40.15, 39.31, 576619) Ticker(T, 40.1, 6/11/2007, 09:54.08, -0.16, 40.2, 40.19, 39.87, 1312959)
Vous pouvez arrêter l'exécution du script en appuyant sur Ctrl+C une fois que vous avez vu assez de résultats.
Remarquez comment les données CSV brutes ont été transformées en objets Ticker structurés. Cette transformation rend les données beaucoup plus faciles à manipuler dans notre pipeline de traitement, car nous pouvons maintenant accéder et manipuler les données d'actions en utilisant les champs définis dans la classe Ticker.
Construction d'un pipeline de données plus complexe
Maintenant, nous allons faire passer notre pipeline de données au niveau supérieur en ajoutant des filtres et en améliorant la présentation des données. Cela facilitera l'analyse et la compréhension des informations avec lesquelles nous travaillons. Nous allons apporter des modifications à notre script ticker.py. Le filtrage des données nous aidera à nous concentrer sur les informations spécifiques qui nous intéressent, et la présentation des données dans un tableau bien formaté les rendra plus lisibles.
Mise à jour du fichier ticker.py
Tout d'abord, ouvrez votre fichier
ticker.pydans le WebIDE. Le WebIDE est un outil qui vous permet d'écrire et d'éditer du code directement dans votre navigateur. Il offre un environnement pratique pour apporter des modifications à vos scripts Python.Ensuite, nous devons remplacer le bloc
if __name__ == '__main__':dans le fichierticker.pypar le code suivant. Ce bloc de code est le point d'entrée de notre script, et en le remplaçant, nous allons modifier la façon dont le script traite et affiche les données.
if __name__ == '__main__':
from follow import follow
import csv
from tableformat import create_formatter, print_table
formatter = create_formatter('text')
lines = follow('stocklog.csv')
rows = csv.reader(lines)
records = (Ticker.from_row(row) for row in rows)
negative = (rec for rec in records if rec.change < 0)
print_table(negative, ['name', 'price', 'change'], formatter)
- Après avoir apporté ces modifications, enregistrez le fichier. Vous pouvez le faire en appuyant sur
Ctrl+Ssur votre clavier ou en sélectionnant "File" → "Save" dans le menu. Enregistrer le fichier garantit que vos modifications sont conservées et peuvent être exécutées plus tard.
Compréhension du pipeline amélioré
Examinons de plus près ce que fait ce pipeline amélioré. Comprendre chaque étape vous aidera à voir comment les différentes parties du code travaillent ensemble pour traiter et afficher les données.
Nous commençons par importer
create_formatteretprint_tabledu moduletableformat. Ce module est déjà configuré pour vous, et il fournit des fonctions qui nous aident à formater et à afficher les données dans un joli tableau.Ensuite, nous créons un formateur de texte en utilisant
create_formatter('text'). Ce formateur sera utilisé pour formater les données d'une manière facile à lire.Maintenant, décomposons le pipeline étape par étape :
follow('stocklog.csv')est une fonction qui génère des lignes à partir du fichierstocklog.csv. Elle surveille en continu le fichier pour détecter de nouvelles données et fournit les lignes une par une.csv.reader(lines)prend les lignes générées parfollowet les analyse en données de ligne. Cela est nécessaire car les données dans le fichier CSV sont au format texte, et nous devons les convertir en un format structuré avec lequel nous pouvons travailler.(Ticker.from_row(row) for row in rows)est une expression générateur qui convertit chaque ligne de données en un objetTicker. Un objetTickerreprésente une action et contient des informations telles que le nom de l'action, le prix et la variation.(rec for rec in records if rec.change < 0)est une autre expression générateur qui filtre les objetsTicker. Elle ne conserve que les objets où la variation du prix de l'action est négative. Cela nous permet de nous concentrer sur les actions dont le prix a diminué.print_table(negative, ['name', 'price', 'change'], formatter)prend les objetsTickerfiltrés et les formate en un tableau en utilisant le formateur que nous avons créé précédemment. Il affiche ensuite le tableau dans la console.
Ce pipeline démontre la puissance des générateurs. Au lieu de charger toutes les données du fichier en mémoire d'un coup, nous enchaînons plusieurs opérations (lecture, analyse, conversion, filtrage) et traitons les données un élément à la fois. Cela économise de la mémoire et rend le code plus efficace.
Exécution du pipeline amélioré
Exécutons le code mis à jour pour voir les résultats.
Tout d'abord, assurez - vous que vous êtes dans le répertoire du projet dans le terminal. Si vous n'y êtes pas déjà, vous pouvez y accéder en utilisant la commande suivante :
cd /home/labex/projectUne fois que vous êtes dans le répertoire du projet, exécutez le script
ticker.pyen utilisant la commande suivante :python3 ticker.pyAprès avoir exécuté le script, vous devriez voir un tableau bien formaté dans le terminal. Ce tableau montre uniquement les actions avec des variations de prix négatives.
name price change ---------- ---------- ---------- C 53.12 -0.21 UTX 70.04 -0.19 AXP 62.86 -0.18 MMM 85.72 -0.22 MCD 51.38 -0.03 WMT 49.85 -0.23 KO 51.6 -0.07 AIG 71.39 -0.14 PG 63.05 -0.02 HD 37.76 -0.19
Si vous avez vu assez de résultats et que vous souhaitez arrêter l'exécution du script, vous pouvez appuyer sur Ctrl+C sur votre clavier.
La puissance des pipelines de générateurs
Ce que nous avons créé ici est un puissant pipeline de traitement de données. Résumons ce qu'il fait :
- Il surveille en continu le fichier
stocklog.csvpour détecter de nouvelles données. Cela signifie que lorsque de nouvelles données sont ajoutées au fichier, le pipeline les traitera automatiquement. - Il analyse les données CSV du fichier en objets
Tickerstructurés. Cela facilite le travail avec les données et l'exécution d'opérations sur elles. - Il filtre les données en fonction de critères spécifiques, dans ce cas, les variations de prix négatives. Cela nous permet de nous concentrer sur les actions qui perdent de la valeur.
- Il formate et présente les données filtrées dans un tableau lisible. Cela facilite l'analyse des données et la formulation de conclusions.
L'un des principaux avantages de l'utilisation de générateurs dans ce pipeline est qu'il utilise un minimum de mémoire. Les générateurs produisent des valeurs à la demande, ce qui signifie qu'ils ne stockent pas toutes les données en mémoire d'un coup. Cela est similaire aux pipes Unix, où chaque composant traite les données et les transmet au composant suivant.
Vous pouvez considérer les générateurs comme des blocs Lego. Tout comme vous pouvez empiler des blocs Lego pour créer différentes structures, vous pouvez combiner des générateurs pour créer des flux de travail de traitement de données puissants. Cette approche modulaire vous permet de construire des systèmes complexes à partir de composants simples et réutilisables.
Résumé
Dans ce laboratoire (lab), vous avez appris à utiliser les générateurs Python pour construire des pipelines de traitement de données efficaces. Vous avez accompli plusieurs tâches importantes, telles que l'utilisation de la fonction follow() pour surveiller un fichier à la recherche de nouvelles données, la création d'une classe Ticker pour représenter les cours d'actions, et la construction d'un pipeline de traitement multi - étapes qui lit, analyse et filtre les données CSV, puis formate et affiche les résultats.
L'approche basée sur les générateurs offre de nombreux avantages, notamment une efficacité mémoire car les données sont traitées à la demande, une modularité permettant de combiner et de réutiliser facilement les composants du pipeline, et une simplicité dans l'expression de flux de données complexes. Ces concepts sont couramment appliqués dans le traitement de données du monde réel, en particulier pour les grands ensembles de données ou les données en continu (streaming data).