Python 如何并行两个迭代器?
这是我问题的后续。我想做Python 如何并行两个迭代器?,python,parallel-processing,multiprocessing,Python,Parallel Processing,Multiprocessing,这是我问题的后续。我想做多处理.Pool.map(比较\u clusters,clusters\u 1,clusters\u 2),其中比较\u clusters是一个函数,clusters\u 1是一个对象列表,clusters\u 2也是一个对象列表。这个问题的答案清楚地表明,与map不同,多处理.Pool.map只能使用一个迭代器,在这种情况下,集群2必须是块大小 所以我的问题是,如何用两个迭代器并行化一个循环 代码 spectra_names, condensed_distance_ma
多处理.Pool.map(比较\u clusters,clusters\u 1,clusters\u 2)
,其中比较\u clusters是一个函数,clusters\u 1是一个对象列表,clusters\u 2也是一个对象列表。这个问题的答案清楚地表明,与map
不同,多处理.Pool.map
只能使用一个迭代器,在这种情况下,集群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)
如果我正确理解了您的代码,那么下面的代码应该可以工作
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\u clusters
功能
考虑到
Blckknght
的答案,您不需要迭代索引来创建一个配对列表,这就是itertools.combinations
的用途。因此,您只需执行pool.map(比较\u clusters,itertools.combines(clusters,2))
,因为combines已经返回元组列表。在Python3.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元组的集群值,我简化了很多事情。对于循环,您根本不需要您的top。我还将反转代码简化为列表理解,而不是每个项调用一次append
的循环
当然,您在循环中所做的另一件事是为spectra\u名称
提取值。与其一次只做一个索引,我建议使用列表理解一次构建所有索引(它可以与上面的池内容分开):
谢谢在我的实际代码中,我有spectra\u names.append(clusters[-1].get\u names())
在循环后获取最后一个值,但在copying@NiekdeKlein:啊,那确实更有意义。我将编辑以删除最后一段(以及它所谈论的片段)。
spectra_names = [c.get_names()[0] for c in clusters]