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?
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.
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.
Dann weisen Sie die Werte im ursprünglichen Datenrahmen neu zu und Sie haben diesen Prozess erfolgreich parallelisiert.
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:
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.
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.
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.
Tags und Links python pandas multiprocessing