IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Parallélisation des calculs dans une DataFrame


Sujet :

Python

  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Novembre 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2022
    Messages : 2
    Par défaut Parallélisation des calculs dans une DataFrame
    Bonjour à tous,

    Je m'excuse par avance, ma question est sans doute un peu bête, mais je cache pas tourner en rond depuis un petit moment sur ce que j'essaye de faire^^ (je connais un peu python, mais je ne maîtrise pas encore bien le multiprocessing)

    Grossièrement, voici ce que je souhaite faire : J'ai une dataframe df qui contient un certain nombre de colonnes, par exemple "A", "B" avec des valeurs préalablement remplies, et j'applique pour chaque ligne de la dataframe une fonction calc() qui vient remplir une colonne résultat.

    Voici un exemple très largement simplifié de ma dataframe et du code qui s'applique dessus.

    Dataframe de départ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        A   B   Resultat
    0  54  99       
    1  23  31        
    2  15  12        
    3   7  65        
    4  85   2        
    5  36  15
    Code (exemple simplifié)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def calc(x, y):
       return(x+y)
     
    for i in range(len(df.index)):
       df.at[i, "Resultat"] = calc(df.at[i, "A"], df.at[i, "B"])
    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        A   B   Resultat
    0  54  99        153
    1  23  31         54
    2  15  12         27
    3   7  65         72
    4  85   2         87
    5  36  15         51
    Pour une approche séquencielle, je ne sais pas si c'est la meilleure façon de faire, probablement pas mais avec ma véritable fonction calc() ça marche bien.

    Le souci, c'est que les calculs exécutés par ma vraie fonction calc() sont en réalité bien plus complexes (notamment elle inclue des calculs mathématiques plus long, et en fonction des données de la ligne traitée par la fonction, elle peut être amenée à aller lire ou écrire des fichiers, faire des requêtes, générer des graphiques, etc.).

    Ainsi, j'aimerais que lorsque le programme traite une ligne, il puisse en traiter une autre en parallèle. (dans le code en exemple, j'ai bien conscience que ça serait inutile, car il serait probablement plus long de créer les processus pour chaque ligne que de faire le calcul sans parallélisation, mais encore une fois, dans la réalité les traitements de ma fonction sont bien plus conséquents). Dans mon cas, j'aimerais notamment que quand une ligne est en cours de traitement exécute une requête, ou lit/écrit un fichier, ou exécute une étape de calcul qui prends du temps, cela ne bloque pas complètement le script, et que les calculs des autres lignes puissent avancer indépendamment.

    Savez-vous comment pourrais-je m'en sortir ? Il y-a-t'il un moyen simple de faire ça ? Désolé par avance, j'ai tendance à penser qu'il y a certainement une solution simple mais je ne la trouve pas, ou alors que ma façon de vouloir faire est incorrecte, car jusqu'à maintenant je n'ai pas réussi à adapter les quelques exemples trouvés sur internet (notamment avec Pool de multiprocessing).

    Par avance, merci pour votre aide !

    Cordialement

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Pour exécuter des calculs en parallèle, le plus simple est d'utiliser le module Python "concurrent.futures". Mais c'est bien sûr possible, aussi, avec "multiprocessing".

    J'ai donné récemment un petit exemple ici:

    https://www.developpez.net/forums/d2.../#post11885924

    Il faut, bien sûr, que chaque calcul ne dépende pas du résultat des autres calculs!

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Salut,
    Citation Envoyé par Serdaigle Voir le message
    Savez-vous comment pourrais-je m'en sortir ? Il y-a-t'il un moyen simple de faire ça ?
    à partir du moment ou "calc" est à durée dépendant de ses traitements, c'est peut être ces traitements qu'il faudrait réorganiser pour pouvoir les paralléliser.
    En gros, si chaque ligne génère un tas de traitements (à faire en parallèle), traiter plusieurs lignes "à la fois" générera d'autant plus de traitements.
    Comme une partie de ces traitements sont des entrées sorties, il va falloir mixer intelligemment multiprocessing et threads.
    Vous avez de la chance, les API sont semblables... mais c'est pas un boulot simple de mettre tout ça en musique.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Nouveau candidat au Club
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Novembre 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2022
    Messages : 2
    Par défaut
    Bonjour,

    Tout d'abord, un grand merci pour vos réponses !

    @tyrtamos
    Je pense effectivement que le code que vous proposez dans votre exemple devrait faire l'affaire ! Je teste ça dès que je peux (et je confirme bien que chaque calcul est indépendant ligne par ligne, dans le sens ou les données d'une ligne n'interviennent jamais dans les calculs d'une autre ligne)

    @wiztricks
    Je pourrais optimiser et paralléliser une partie des calculs au sein même de ma fonction "calc". Dans mon cas, et pour chaque ligne de la dataframe, calc() applique en fait une série de sous-fonctions f1, f2, f3 etc. qui schématiquement pourrait nous donner un graphe de calcul comme suit (encore une fois, ce schéma est simplifié, dans la réalité il y a plus de noeuds et niveaux intermédiaires que ci-dessous) :

    Nom : arbre_de_calcul.png
Affichages : 624
Taille : 10,0 Ko

    Dans cet exemple, je pourrais paralléliser f1 et f2, et dire à f3 de s'exécuter lorsque ses dépendances sont terminées (en l’occurrence f1 et f2). Puis généraliser ce concept à un arbre de calcul bien plus grand. C'est l'idéal que je voudrais viser, mais pour le moment il me semble plus simple à mon niveau de commencer par paralléliser chaque ligne indépendante de la DataFrame. Dans un second temps j'essayerai effectivement cette option

    Encore merci pour votre appui !

    Cordialement

  5. #5
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 199
    Par défaut
    Hello,
    voir aussi la bibliothèque pandarallel

    Pandaral.lel provides a simple way to parallelize your pandas operations on all your CPUs by changing only one line of code.
    It also displays progress bars.
    Ami calmant, J.P

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Salut,

    Citation Envoyé par Serdaigle Voir le message
    mais pour le moment il me semble plus simple à mon niveau de commencer par paralléliser chaque ligne indépendante de la DataFrame
    Pour l'instant vous essayez de mettre au point la structure d'un programme où pourrait être parallélisé le traitement des lignes d'un tableau.
    Que ce tableau soit un dataframe Pandas ou une simple liste ne devrait pas changer grand chose à sa structure et aux mécanismes à mettre en œuvre.

    Et si vous aviez ouvert la documentation du module threading (en première approximation, c'est avec des threads qu'on parallélise) vous auriez déjà une idée des alternatives (concurrent.futures, multiprocessing) et des modules complémentaires (queue,...).

    Dès qu'on sort des exemples basiques, c'est la conception qui fera la différence car elle devra tirer profit/faire avec les fonctionnalités apportées. Et pour espérer y arriver il aura fallu passer un temps certain à comprendre comment ça fonctionne, tester ses idées, le cas échéant, comprendre pourquoi elles ne fonctionnent pas.... histoire de définir la structure à mettre en place dans chaque cas particulier.
    note: une bibliothèque est juste là pour s'éviter à avoir à recoder du basique dès qu'on se lance dans ce genre d'aventure. On gagne du temps en réalisation mais le travail de conception reste à faire.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Des calculs dans une base de données
    Par elharrak dans le forum NetBeans
    Réponses: 1
    Dernier message: 19/06/2012, 16h30
  2. Insérer des calculs dans une page HTML
    Par cassiopee64 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 17/10/2009, 12h46
  3. Réponses: 8
    Dernier message: 27/12/2007, 12h55
  4. Réponses: 7
    Dernier message: 07/03/2007, 14h14
  5. Récupérer la valeur des champs calculés dans une requète SQL dans vba
    Par FrédéricCM dans le forum Requêtes et SQL.
    Réponses: 12
    Dernier message: 28/06/2006, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo