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}
========
12 Stimmen
Zu meiner Überraschung konnte ich weder die
partial
nochlambda
dies tun. Ich denke, es hat mit der seltsamen Art und Weise zu tun, wie Funktionen an die Unterprozesse übergeben werden (überpickle
).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)
5 Stimmen
@Syrtis_Major , bitte editieren Sie keine OP-Fragen, die Antworten, die bereits gegeben wurden, effektiv verdrehen. Hinzufügen von
return
àharvester()
hat die Antwort von @senderie als ungenau bezeichnet. Das ist für künftige Leser nicht hilfreich.3 Stimmen
Ich würde sagen, eine einfache Lösung wäre, alle Args in ein Tupel zu packen und es in der ausführenden Funktion zu entpacken. Ich habe dies getan, wenn ich komplizierte mehrere Args an eine Funktion senden musste, die von einem Pool von Prozessen ausgeführt wird.
0 Stimmen
Vielleicht gibt es eine gewisse Komplexität, die ich für diesen speziellen Anwendungsfall vermisse, aber ein Teil funktioniert für meinen ähnlichen Anwendungsfall und ist sehr prägnant und einfach zu verwenden. python.omics.wiki/multiprocessing_map/