895 Stimmen

Wie man multiprocessing pool.map mit mehreren Argumenten verwendet

In der Python multiprocessing Bibliothek, gibt es eine Variante von pool.map die mehrere Argumente unterstützt?

import multiprocessing

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

12 Stimmen

Zu meiner Überraschung konnte ich weder die partial noch lambda dies tun. Ich denke, es hat mit der seltsamen Art und Weise zu tun, wie Funktionen an die Unterprozesse übergeben werden (über pickle ).

15 Stimmen

@senderle: Dies ist ein Fehler in Python 2.6, der aber mit 2.7 behoben wurde: bugs.python.org/issue5228

3 Stimmen

Ersetzen Sie einfach pool.map(harvester(text,case),case, 1) von: pool.apply_async(harvester(text,case),case, 1)

3voto

cgnorthcutt Punkte 3434

Es gibt viele Antworten hier, aber keine scheint Python 2/3 kompatiblen Code zu liefern, der auf jeder Version funktioniert. Wenn Sie wollen, dass Ihr Code einfach arbeiten funktioniert dies für beide Python-Versionen:

# For python 2/3 compatibility, define pool context manager
# to support the 'with' statement in Python 2
if sys.version_info[0] == 2:
    from contextlib import contextmanager
    @contextmanager
    def multiprocessing_context(*args, **kwargs):
        pool = multiprocessing.Pool(*args, **kwargs)
        yield pool
        pool.terminate()
else:
    multiprocessing_context = multiprocessing.Pool

Danach können Sie Multiprocessing auf die reguläre Python-3-Art verwenden, wie Sie wollen. Zum Beispiel:

def _function_to_run_for_each(x):
       return x.lower()
with multiprocessing_context(processes=3) as pool:
    results = pool.map(_function_to_run_for_each, ['Bob', 'Sue', 'Tim'])    print(results)

wird in Python 2 oder Python 3 funktionieren.

2voto

A. Nodar Punkte 11

Dies ist ein Beispiel für die Routine, die ich verwende, um mehrere Argumente an eine Ein-Argument-Funktion zu übergeben, die in einer pool.imap Gabelung:

from multiprocessing import Pool

# Wrapper of the function to map:
class makefun:
    def __init__(self, var2):
        self.var2 = var2
    def fun(self, i):
        var2 = self.var2
        return var1[i] + var2

# Couple of variables for the example:
var1 = [1, 2, 3, 5, 6, 7, 8]
var2 = [9, 10, 11, 12]

# Open the pool:
pool = Pool(processes=2)

# Wrapper loop
for j in range(len(var2)):
    # Obtain the function to map
    pool_fun = makefun(var2[j]).fun

    # Fork loop
    for i, value in enumerate(pool.imap(pool_fun, range(len(var1))), 0):
        print(var1[i], '+' ,var2[j], '=', value)

# Close the pool
pool.close()

2voto

Jaime Punkte 11
text = "test"

def unpack(args):
    return args[0](*args[1:])

def harvester(text, case):
    X = case[0]
    text+ str(X)

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=6)
    case = RAW_DATASET
    # args is a list of tuples 
    # with the function to execute as the first item in each tuple
    args = [(harvester, text, c) for c in case]
    # doing it this way, we can pass any function
    # and we don't need to define a wrapper for each different function
    # if we need to use more than one
    pool.map(unpack, args)
    pool.close()
    pool.join()

2voto

Aenaon Punkte 2829

Dies könnte eine weitere Option sein. Der Trick liegt in der wrapper Funktion, die eine andere Funktion zurückgibt, die an pool.map . Der folgende Code liest ein Eingabe-Array und gibt für jedes (eindeutige) Element darin zurück, wie oft (d.h. wie oft) dieses Element in dem Array erscheint.

np.eye(3) = [ [1. 0. 0.]
              [0. 1. 0.]
              [0. 0. 1.]]

dann erscheint die Null 6 Mal und die Eins 3 Mal

import numpy as np
from multiprocessing.dummy import Pool as ThreadPool
from multiprocessing import cpu_count

def extract_counts(label_array):
    labels = np.unique(label_array)
    out = extract_counts_helper([label_array], labels)
    return out

def extract_counts_helper(args, labels):
    n = max(1, cpu_count() - 1)
    pool = ThreadPool(n)
    results = {}
    pool.map(wrapper(args, results), labels)
    pool.close()
    pool.join()
    return results

def wrapper(argsin, results):
    def inner_fun(label):
        label_array = argsin[0]
        counts = get_label_counts(label_array, label)
        results[label] = counts
    return inner_fun

def get_label_counts(label_array, label):
    return sum(label_array.flatten() == label)

if __name__ == "__main__":
    img = np.ones([2,2])
    out = extract_counts(img)
    print('input array: \n', img)
    print('label counts: ', out)
    print("========")

    img = np.eye(3)
    out = extract_counts(img)
    print('input array: \n', img)
    print('label counts: ', out)
    print("========")

    img = np.random.randint(5, size=(3, 3))
    out = extract_counts(img)
    print('input array: \n', img)
    print('label counts: ', out)
    print("========")

Sie sollten es bekommen:

input array: 
 [[1. 1.]
 [1. 1.]]
label counts:  {1.0: 4}
========
input array: 
 [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
label counts:  {0.0: 6, 1.0: 3}
========
input array: 
 [[4 4 0]
 [2 4 3]
 [2 3 1]]
label counts:  {0: 1, 1: 1, 2: 2, 3: 2, 4: 3}
========

2voto

Dipankar Biswas Punkte 131
import time
from multiprocessing import Pool

def f1(args):
    vfirst, vsecond, vthird = args[0] , args[1] , args[2]
    print(f'First Param: {vfirst}, Second value: {vsecond} and finally third value is: {vthird}')
    pass

if __name__ == '__main__':
    p = Pool()
    result = p.map(f1, [['Dog','Cat','Mouse']])
    p.close()
    p.join()
    print(result)

0 Stimmen

Eine Erklärung wäre angebracht. Zum Beispiel, was ist die Idee/der Sinn? Bitte antworten Sie bis Bearbeitung (Änderung) Ihrer Antwort , nicht hier in den Kommentaren ( ohne "Bearbeiten:", "Aktualisieren:" oder ähnlich - die Antwort sollte so aussehen, als wäre sie heute geschrieben worden).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X