这是我的问题Paralel for loop, map() works, pool.map() gives TypeError的后续跟进。我想做multiprocessing.Pool.map(compare_clusters, clusters_1, clusters_2)
,其中compare_clusters是一个函数,clusters_1是一个对象列表,clusters_2也是一个对象列表。该问题的answer清楚地表明,与map
不同,multiprocessing.Pool.map
只能使用一个迭代器,在这种情况下,clusters_2
必须是块大小。
所以我的问题是,如何将循环与两个迭代器并行化?
代码
spectra_names, condensed_distance_matrix, index_0 = [], [], 0
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
if index_0 == index_1:
index_0 += 1
spectra_names.append(clusters[index_1].get_names()[0])
try:
distance = 1/float(compare_clusters(clusters[index_1], clusters[index_2],maxiter=50))
except:
distance = 10
condensed_distance_matrix.append(distance)
我是如何尝试并行化的
from multiprocessing import Pool
condensed_distance_matrix, spectra_names, index_0, clusters_1, clusters_2 = [], [], 0, [], []
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
if index_0 == index_1:
index_0 += 1
spectra_names.append(clusters[index_1].get_names()[0])
clusters_1.append(clusters[index_1])
clusters_2.append(clusters[index_2])
pool = Pool()
condensed_distance_matrix_values = pool.map(compare_clusters, clusters_1, clusters_2)
for value in condensed_distance_matrix_values :
try:
distance = 1/float(value)
except:
distance = 10
condensed_distance_matrix.append(distance)
答案 0 :(得分:2)
如果我正确理解您的代码,则以下内容应该有效
from multiprocessing import Pool
condensed_distance_matrix = []
spectra_names = []
index_0 = 0
cluster_pairs = []
for index_1, index_2 in itertools.combinations(range(len(clusters)), 2):
if index_0 == index_1:
index_0 += 1
spectra_names.append(clusters[index_1].get_names()[0])
cluster_pairs.append((clusters[index_1], clusters[index_2]))
pool = Pool()
condensed_distance_matrix_values = pool.map(compare_clusters, cluster_pairs)
for value in condensed_distance_matrix_values :
try:
distance = 1/float(value)
except:
distance = 10
condensed_distance_matrix.append(distance)
因此,不是创建两个包含单个群集的列表,而是创建一个包含群集对的元组。新列表中的每对都是您要比较的群集对。您可能需要相应地调整compare_clusters
函数。
考虑到Blckknght
的答案,您不需要迭代索引来创建itertools.combinations
所针对的列表。所以你可以pool.map(compare_clusters, itertools.combinations(clusters, 2))
,因为组合已经返回了一个元组列表。
答案 1 :(得分:1)
在Python 3.3及更高版本中,您可以使用pool.starmap
。在早期版本中,您需要编写辅助函数:
def do_comparison(tupl):
x, y = tupl # unpack arguments
return compare_clusters(x, y)
pool = Pool()
values = pool.map(do_comparison, itertools.combinations(clusters, 2))
condensed_distance_matrix = [1 / float(v) if v != 0 else 10 for v in values]
我通过完全避免索引简化了一些事情,而是直接生成2元组的集群值。你根本不需要你的顶级for
循环。我还将反转代码简化为列表理解,而不是每个项目调用一次append
的循环。
当然,你在循环中做的另一件事是提取spectra_names
的值。我建议不要一次只做一个索引,而是使用列表推导来一次构建它(它可以与上面的池中的东西分开):
spectra_names = [c.get_names()[0] for c in clusters]