并行for循环,map()工作,pool.map()给出TypeError

时间:2013-10-23 12:20:49

标签: python multiprocessing pool

我正在制作一个浓缩(仅右上角)距离矩阵。距离的计算需要一些时间,所以我想对for循环进行并行化。未完全化的循环看起来像

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)

其中cluster是要比较的对象列表,compare_clusters()是似然函数,1/compare_clusters()是两个对象之间的距离。

我试图通过将距离函数移出循环来对其进行并行化

from multiprocessing import Pool
condensed_distance_matrix = []
spectra_names = []
index_0 = 0
clusters_1 = []
clusters_2 = []
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)

在准备之前,我尝试使用相同的代码,但map()代替pool.map()。这按我的意愿行事。但是,使用pool.map()时出现错误

  File "C:\Python27\lib\multiprocessing\pool.py", line 225, in map
    return self.map_async(func, iterable, chunksize).get()
  File "C:\Python27\lib\multiprocessing\pool.py", line 288, in map_async
    result = MapResult(self._cache, chunksize, len(iterable), callback)
  File "C:\Python27\lib\multiprocessing\pool.py", line 551, in __init__
    self._number_left = length//chunksize + bool(length % chunksize)
TypeError: unsupported operand type(s) for //: 'int' and 'list'

我在这里缺少什么?

1 个答案:

答案 0 :(得分:4)

来自Pool.map's documentation

  

map()内置函数的并行等价物(它仅支持一个可迭代的参数)。它会阻塞,直到结果准备就绪。

对于普通map,您可以提供多个迭代。例如,

>>> map(lambda x,y: x+y, "ABC", "DEF")
['AD', 'BE', 'CF']

但你不能用Pool.map做到这一点。第三个参数被解释为chunksize。当它需要int时,你给它一个列表。

也许你可以通过组合你的列表来传递一个可迭代的内容:

pool.map(lambda (a,b): compare_clusters(a,b), zip(clusters_1, clusters_2))

我没有使用pool.map对其进行测试,但此策略适用于普通map

>>> map(lambda (a,b): a+b, zip("ABC", "DEF"))
['AD', 'BE', 'CF']