Pandas df.iterrow () Parallelisierung

9

Ich möchte den folgenden Code parallelisieren:

%Vor%

Ich habe versucht, multiprocessing.Pool() zu verwenden, da jede Zeile unabhängig verarbeitet werden kann, aber ich kann nicht herausfinden, wie man den DataFrame teilt. Ich bin mir auch nicht sicher, ob dies der beste Ansatz ist, um eine Parallelisierung mit Pandas zu erreichen. Irgendwelche Hilfe?

    
alec_djinn 01.11.2016, 09:39
quelle

2 Antworten

18

Wie @Khris in seinem Kommentar sagte, sollten Sie Ihren Datenrahmen in ein paar große Blöcke aufteilen und über jeden Block parallel durchlaufen. Sie können den Datenrahmen willkürlich in Blöcke mit zufälliger Größe unterteilen, aber es ist sinnvoller, den Datenrahmen in gleich große Blöcke aufzuteilen, basierend auf der Anzahl der Prozesse, die Sie verwenden möchten. Glücklicherweise hat jemand anderes bereits herausgefunden, wie man diesen Teil macht für uns:

%Vor%

Dies erstellt eine Liste, die unseren Datenrahmen in Blöcken enthält. Nun müssen wir es zusammen mit einer Funktion, die die Daten manipuliert, in unseren Pool eingeben.

%Vor%

An diesem Punkt wird result eine Liste sein, die jeden Chunk enthält, nachdem er manipuliert wurde. In diesem Fall wurden alle Werte quadriert. Das Problem besteht nun darin, dass der ursprüngliche Datenrahmen nicht geändert wurde. Daher müssen wir alle vorhandenen Werte durch die Ergebnisse aus unserem Pool ersetzen.

%Vor%

Nun, meine Funktion, meinen Datenrahmen zu manipulieren, ist vektorisiert und wäre wahrscheinlich schneller gewesen, wenn ich ihn einfach auf die Gesamtheit meines Datenrahmens angewendet hätte, anstatt ihn in Stücke zu teilen. In Ihrem Fall würde Ihre Funktion jedoch über jede Zeile jedes Chunks iterieren und dann den Chunk zurückgeben. Dadurch können Sie num_process rows gleichzeitig verarbeiten.

%Vor%

Dann weisen Sie die Werte im ursprünglichen Datenrahmen neu zu und Sie haben diesen Prozess erfolgreich parallelisiert.

Wie viele Prozesse sollte ich verwenden?

Ihre optimale Leistung hängt von der Antwort auf diese Frage ab. Während "ALLE PROZESSE !!!!" ist eine Antwort, eine bessere Antwort ist viel nuancierter. Ab einem bestimmten Punkt erzeugt mehr Prozesse bei einem Problem mehr Overhead als es wert ist. Dies wird als Amdahl'sches Gesetz bezeichnet. Auch hier haben wir das Glück, dass andere diese Frage bereits beantwortet haben:

  1. Python-Multiprocessing-Pool-Prozesslimit
  2. Wie viele Prozesse sollte ich parallel ausführen?

Ein guter Standard ist die Verwendung von multiprocessing.cpu_count() , was das Standardverhalten von multiprocessing.Pool ist. Gemäß der Dokumentation "Wenn Prozesse keine sind, wird die von cpu_count ( ) wird eingesetzt." Deshalb habe ich num_processes am Anfang auf multiprocessing.cpu_count() gesetzt. Auf diese Weise erhalten Sie die Vorteile, wenn Sie zu einer robusteren Maschine wechseln, ohne die Variable num_processes direkt ändern zu müssen.

    
TheF1rstPancake 04.11.2016, 17:15
quelle
5

Ein schneller Weg (ungefähr 10% in meinem Fall):

Hauptunterschiede zur angenommenen Antwort: Verwenden Sie pd.concat und np.array_split , um das dataframre zu teilen und zu verbinden.

%Vor%

Dabei ist func die Funktion, die Sie auf df anwenden möchten. Verwenden Sie partial(func, arg=arg_val) für mehr als ein Argument.

    
ic_fl2 09.08.2017 14:54
quelle

Tags und Links