Utiliser les générateurs pour les pipelines de Stocksim

PythonPythonBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

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.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") python/ObjectOrientedProgrammingGroup -.-> python/constructor("Constructor") python/FileHandlingGroup -.-> python/file_reading_writing("Reading and Writing Files") python/FileHandlingGroup -.-> python/file_operations("File Operations") python/AdvancedTopicsGroup -.-> python/generators("Generators") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/classes_objects -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} python/constructor -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} python/file_reading_writing -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} python/file_operations -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} python/generators -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} python/data_collections -.-> lab-132523{{"Utiliser les générateurs pour les pipelines de Stocksim"}} end

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 fonction follow du module follow.
  • import csv : Cela importe le module csv, qui est utilisé pour lire et écrire des fichiers CSV en Python.
  • lines = follow('stocklog.csv') : Cela appelle la fonction follow avec le nom de fichier stocklog.csv. La fonction follow renvoie 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 fonction csv.reader() prend les lignes générées par la fonction follow et les analyse en lignes de données CSV.
  • La boucle for itè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 :

  1. follow('stocklog.csv') crée un générateur. Ce générateur suit le fichier stocklog.csv et produit de nouvelles lignes au fur et à mesure qu'elles sont ajoutées au fichier.
  2. csv.reader(lines) prend les lignes générées par la fonction follow et les analyse en données de ligne CSV. Il comprend la structure des fichiers CSV et divise les lignes en valeurs individuelles.
  3. La boucle for itè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

  1. 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 classe Ticker.

  2. Maintenant, ajoutons le code suivant à votre fichier ticker.py nouvellement créé. Ce code définira notre classe Ticker et 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)
  1. Après avoir ajouté le code, enregistrez le fichier. Vous pouvez le faire en appuyant sur Ctrl+S 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 code

Examinons de plus près ce que ce code fait étape par étape :

  1. Au début du code, nous importons Structure et les types de champs du module structure.py. Ce module a déjà été configuré pour vous. Ces importations sont essentielles car elles fournissent les éléments de base pour notre classe Ticker. La classe Structure sera la classe de base de notre classe Ticker, et les types de champs comme String, Float et Integer définiront les types de données de nos champs de données d'actions.

  2. Ensuite, nous définissons une classe Ticker qui hérite de Structure. 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.
    • date et time : 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.
  3. 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 fichier ticker.py.

    • follow('stocklog.csv') est une fonction qui génère des lignes à partir du fichier stocklog.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 objet Ticker. De cette façon, nous transformons les données CSV brutes en objets structurés plus faciles à manipuler.
    • La boucle for itère sur ces objets Ticker et 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 :

  1. 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/project
  2. Une fois que vous êtes dans le bon répertoire, exécutez le script ticker.py en utilisant la commande suivante :

    python3 ticker.py
  3. Aprè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.

✨ Vérifier la solution et pratiquer

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

  1. Tout d'abord, ouvrez votre fichier ticker.py dans 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.

  2. Ensuite, nous devons remplacer le bloc if __name__ == '__main__': dans le fichier ticker.py par 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)
  1. Après avoir apporté ces modifications, enregistrez le fichier. Vous pouvez le faire en appuyant sur Ctrl+S sur 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.

  1. Nous commençons par importer create_formatter et print_table du module tableformat. 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.

  2. 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.

  3. Maintenant, décomposons le pipeline étape par étape :

    • follow('stocklog.csv') est une fonction qui génère des lignes à partir du fichier stocklog.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 par follow et 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 objet Ticker. Un objet Ticker repré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 objets Ticker. 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 objets Ticker filtré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.

  1. 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/project
  2. Une fois que vous êtes dans le répertoire du projet, exécutez le script ticker.py en utilisant la commande suivante :

    python3 ticker.py
  3. Aprè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 :

  1. Il surveille en continu le fichier stocklog.csv pour détecter de nouvelles données. Cela signifie que lorsque de nouvelles données sont ajoutées au fichier, le pipeline les traitera automatiquement.
  2. Il analyse les données CSV du fichier en objets Ticker structurés. Cela facilite le travail avec les données et l'exécution d'opérations sur elles.
  3. 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.
  4. 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.

✨ Vérifier la solution et pratiquer

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).