Gibt es in der Python-Multiprozessor-Bibliothek eine Variante von pool.map, die mehrere Argumente unterstützt?
text = "test"
def harvester(text, case):
X = case[0]
text+ str(X)
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=6)
case = RAW_DATASET
pool.map(harvester(text,case),case, 1)
pool.close()
pool.join()
python
multiprocessing
user642897
quelle
quelle
partial
nochlambda
tun. Ich denke, es hat mit der seltsamen Art und Weise zu tun, wie Funktionen an die Unterprozesse (viapickle
) übergeben werden.pool.map(harvester(text,case),case, 1)
durch:pool.apply_async(harvester(text,case),case, 1)
return
zuharvester()
@senderies Antwort wurde ungenau. Das hilft zukünftigen Lesern nicht.Antworten:
Die Antwort darauf ist version- und situationsabhängig. Die allgemeinste Antwort für neuere Versionen von Python (seit 3.3) wurde unten von JF Sebastian beschrieben . 1 Es wird die
Pool.starmap
Methode verwendet, die eine Folge von Argumenttupeln akzeptiert. Anschließend werden die Argumente aus jedem Tupel automatisch entpackt und an die angegebene Funktion übergeben:Für frühere Versionen von Python müssen Sie eine Hilfsfunktion schreiben, um die Argumente explizit zu entpacken. Wenn Sie verwenden möchten
with
, müssen Sie auch einen Wrapper schreiben, um sichPool
in einen Kontextmanager zu verwandeln . (Danke an Myon für diesen Hinweis.)In einfacheren Fällen können Sie mit einem festen zweiten Argument auch verwenden
partial
, jedoch nur in Python 2.7+.1. Ein Großteil davon wurde von seiner Antwort inspiriert, die wahrscheinlich stattdessen hätte akzeptiert werden sollen. Aber da dieser oben feststeckt, schien es am besten, ihn für zukünftige Leser zu verbessern.
quelle
=RAW_DATASET
Standardwert zuzuweisencase
. Andernfallspool.map
wird über die mehreren Argumente verwirrt.text
Variablen in Ihrem Beispiel passiert ? Warum wirdRAW_DATASET
scheinbar zweimal bestanden. Ich denke, Sie könnten einen Tippfehler haben?with .. as ..
Ich bin mir nicht sicher, warum ich es benutzeAttributeError: __exit__
, aber es funktioniert gut, wenn ich nur anrufe undpool = Pool();
dann manuell schließepool.close()
(python2.7)Pool
Objekte erst in Python 3.3 zu Kontextmanagern werden. Ich habe eine einfache Wrapper-Funktion hinzugefügt, die einenPool
Kontextmanager zurückgibt .Python 3.3 enthält folgende
pool.starmap()
Methode :Für ältere Versionen:
Ausgabe
Beachten Sie, wie
itertools.izip()
unditertools.repeat()
hier verwendet werden.Aufgrund des von @unutbu erwähnten Fehlers können Sie
functools.partial()
oder ähnliche Funktionen in Python 2.6 nicht verwenden , daher sollte die einfache Wrapper-Funktionfunc_star()
explizit definiert werden. Siehe auch die vonuptimebox
.quelle
func_star
:def func_star((a, b))
. Natürlich funktioniert dies nur für eine feste Anzahl von Argumenten, aber wenn dies der einzige Fall ist, den er hat, ist es besser lesbar.f((a,b))
Syntax ist in py3k veraltet und wird entfernt. Und das ist hier unnötig.func = lambda x: func(*x)
anstatt eine Wrapper-Funktion zu definierenfunc_star()
obenstarstarmap
.Ich denke, das Folgende wird besser sein
Ausgabe
quelle
args
direktadd
. Sie funktioniert für eine beliebige Anzahl von Argumenten:def add(args): (x,y) = args
lambda
Funktion verwenden, anstatt zu definierenmulti_run_wrapper(..)
lambda
funktioniert die Verwendung von a nicht, weilpool.map(..)
versucht wird, die gegebene Funktion zu übernehmenadd
in einer Liste speichern möchten ?Verwenden von Python 3.3+ mit
pool.starmap():
Ergebnis:
Sie können auch weitere Argumente zip (), wenn Sie möchten:
zip(a,b,c,d,e)
Wenn Sie einen konstanten Wert als Argument übergeben möchten, müssen Sie ihn verwenden
import itertools
und dannzip(itertools.repeat(constant), a)
zum Beispiel.quelle
Nachdem ich in der Antwort von JF Sebastian von itertools erfahren hatte, beschloss ich, noch einen Schritt weiter zu gehen und ein
parmap
Paket zu schreiben , das sich um Parallelisierung, Angebotmap
undstarmap
Funktionen von Python-2.7 und Python-3.2 (und später auch) kümmert und eine beliebige Anzahl von Positionsargumenten annehmen kann .Installation
So parallelisieren Sie:
Ich habe Parmap auf PyPI und in ein Github-Repository hochgeladen .
Als Beispiel kann die Frage wie folgt beantwortet werden:
quelle
# "Wie man mehrere Argumente nimmt".
quelle
Es gibt eine Verzweigung mit dem
multiprocessing
Namen Pathos ( Hinweis: Verwenden Sie die Version auf Github ), die nicht benötigt wird.starmap
Die Map-Funktionen spiegeln die API für die Python-Map wider , sodass die Map mehrere Argumente annehmen kann. Mitpathos
können Sie im Allgemeinen auch Multiprocessing im Interpreter ausführen, anstatt im__main__
Block stecken zu bleiben . Pathos wird nach einigen milden Aktualisierungen veröffentlicht - hauptsächlich Konvertierung auf Python 3.x.pathos
Es gibt verschiedene Möglichkeiten, wie Sie das genaue Verhalten ermitteln könnenstarmap
.quelle
Sie können die folgenden zwei Funktionen verwenden, um zu vermeiden, dass für jede neue Funktion ein Wrapper geschrieben wird:
Verwenden Sie die Funktion
function
mit den Listen der Argumentearg_0
,arg_1
undarg_2
wie folgt dar :quelle
Eine bessere Lösung für Python2:
2 3 4
1 2 3
0 1 2
aus[]:
[3, 5, 7]
quelle
Eine andere einfache Alternative besteht darin, Ihre Funktionsparameter in ein Tupel zu packen und dann die Parameter, die ebenfalls in Tupel übergeben werden sollen, zu verpacken. Dies ist möglicherweise nicht ideal, wenn Sie mit großen Datenmengen arbeiten. Ich glaube, es würde Kopien für jedes Tupel machen.
Gibt die Ausgabe in zufälliger Reihenfolge an:
quelle
Ein besserer Weg ist die Verwendung von Decorator, anstatt die Wrapper-Funktion von Hand zu schreiben . Insbesondere wenn Sie viele Funktionen zuordnen müssen, spart der Dekorateur Zeit, indem er das Schreiben eines Wrappers für jede Funktion vermeidet. Normalerweise ist eine dekorierte Funktion nicht auswählbar, wir können sie jedoch verwenden
functools
, um sie zu umgehen . Weitere Diskussionen finden Sie hier .Hier das Beispiel
Dann können Sie es mit komprimierten Argumenten zuordnen
Natürlich können Sie
Pool.starmap
in Python 3 (> = 3.3) immer verwenden, wie in anderen Antworten erwähnt.quelle
itertools.product
anstelle von verwendenzip
.Eine andere Möglichkeit besteht darin, eine Liste von Listen an eine Routine mit einem Argument zu übergeben:
Man kann dann eine Liste mit Argumenten mit seiner Lieblingsmethode erstellen.
quelle
Hier ist eine andere Möglichkeit, IMHO einfacher und eleganter zu gestalten als alle anderen Antworten.
Dieses Programm verfügt über eine Funktion, die zwei Parameter verwendet, diese ausgibt und auch die Summe ausgibt:
Ausgabe ist:
Weitere Informationen finden Sie in den Python-Dokumenten:
https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool
Überprüfen Sie insbesondere die
starmap
Funktion.Ich verwende Python 3.6 und bin mir nicht sicher, ob dies mit älteren Python-Versionen funktioniert
Warum es in den Dokumenten kein sehr einfaches Beispiel wie dieses gibt, weiß ich nicht genau.
quelle
Ab Python 3.4.4 können Sie multiprocessing.get_context () verwenden, um ein Kontextobjekt für die Verwendung mehrerer Startmethoden abzurufen:
Oder Sie ersetzen einfach
durch:
quelle
Hier gibt es viele Antworten, aber keine scheint Python 2/3-kompatiblen Code bereitzustellen, der für jede Version geeignet ist. Wenn Sie möchten, dass Ihr Code nur funktioniert , funktioniert dies für beide Python-Versionen:
Danach können Sie die Mehrfachverarbeitung auf reguläre Python 3-Weise verwenden, wie Sie möchten. Zum Beispiel:
funktioniert in Python 2 oder Python 3.
quelle
In der offiziellen Dokumentation heißt es, dass es nur ein iterierbares Argument unterstützt. In solchen Fällen verwende ich gerne apply_async. In Ihrem Fall würde ich tun:
quelle
quelle
Dies ist ein Beispiel für die Routine, mit der ich mehrere Argumente an eine Funktion mit einem Argument übergebe, die in einergabelung pool.imap verwendet wird:
quelle
Für Python2 können Sie diesen Trick verwenden
quelle