Параллельный расчет на разреженной матрице в Python - PullRequest
0 голосов
/ 01 января 2019

У меня есть большой [NumPy] вектор X и функция сравнения f(x,y).Мне нужно найти все пары элементов X, для которых f(X[I],X[j])<T для некоторого порога T. Это хорошо работает:

good_inds = {}
for i in range(0,len(X)):
   for j in range(x+1,len(X)):
       score = f(X[i],X[j])
       if score<T:
           good_inds[x,y] = score

Это фактически создает словарь, который представляет представление разреженной матрицы.Проблема в том, что это довольно медленно, и я хочу распараллелить этот процесс.Пожалуйста, сообщите.

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Итак.Очевидно, SciPy уже достаточно хорош.

full_dist_mat = spatial.distance.squareform( spatial.distance.pdist(vects2, metric='cosine'))

уже оптимизирован.Запуск 2000 векторов занимает 1,3 секунды в лаборатории Jupyter на MacBook Pro.

0 голосов
/ 01 января 2019

Это хорошо подходит для multiprocessing.Pool.

Создайте свой пустой массив, затем создайте итератор из 2-х кортежей всех возможных значений i и j.Например, с itertools.combinations.

In [1]: import itertools

In [7]: list(itertools.combinations(range(4), 2))                                                        
Out[7]: [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

(Конечно, вы должны использовать длину вашего вектора в качестве аргумента для range.)

Напишите следующую функцию:

def worker(pair):
    i, j = pair
    rv = False
    if f(X[i],X[j]) < T:
       rv = True
    return (i, j, rv)

Создайте Pool и запустите imap_unordered:

p = multiprocessing.Pool()
for i, j, result in p.imap_unordered(worker, itertools.combinations(range(len(X)), 2)):
    if result:
        print('Good pair:', i, j)
        # do something with the results...

Это позволит запустить столько рабочих, сколько у вас процессорных ядер.

...