1

凝縮された(右上のみ)距離行列を作成しています。距離の計算に時間がかかるので、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)

ここで、clusters は比較するオブジェクトのリスト、compare_clusters()は尤度関数、1/compare_clusters()は 2 つのオブジェクト間の距離です。

そのように距離関数をループの外に移動して、それを並列化しようとしました

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'

ここで何が欠けていますか?

4

1 に答える 1

4

Pool.mapのドキュメントから:

map() 組み込み関数と同等の並列関数 (ただし、反復可能な引数は 1 つしかサポートされません)。結果が準備できるまでブロックします。

通常mapの場合、複数のイテラブルを指定できます。例えば、

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

しかし、あなたはこれを行うことはできませんPool.map。3 番目の引数は として解釈されchunksizeます。int が必要なときにリストを指定しています。

おそらく、リストを組み合わせることで、単一の iterable だけを渡すことができます。

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']
于 2013-10-23T12:26:37.197 に答える