3

我正在查看joblib示例,但我无法弄清楚如何在矩阵上执行并行 for 循环。我正在计算矩阵行之间的成对距离度量。所以我在做:

N, _ = data.shape
upper_triangle = [(i, j) for i in range(N) for j in range(i + 1, N)]
dist_mat = np.zeros((N,N))  

for (i, j) in upper_triangle:
    dist_mat[i,j] = dist_fun(data[i], data[j])
    dist_mat[j,i] = dist_mat[i,j]

其中dist_fun需要两个向量并计算距离。我怎样才能使这个循环并行,因为调用dist_fun可以相互独立。


编辑:我使用的距离函数fastdtw不是那么快。所以我认为真的想要并行化这个。使用:

dist_mat = pdist(data, lambda x,y : fastdtw(x,y, dist=euclidean)[0])

我得到 58.1084 秒的执行时间,并使用:

dist_mat = np.zeros((N,N))
for (i,j), _ in np.ndenumerate(dist_mat):
    dist_mat[i,j], _ = fastdtw(data[i,:], timeseries[j,:], dist=euclidean)

我得到 116.36 秒并使用:

upper_triangle = [(i,j) for i in range(N) for j in range(i+1, N)]
dist_mat = np.zeros((N,N))

for (i,j) in upper_triangle:
    dist_mat[i,j], _ = fastdtw(data[i,:], data[j,:], dist=euclidean)
    dist_mat[j,i] = dist_mat[i,j]

我得到 55.62 秒。在这里N=33。是否scipy自动使用所有可用内核?


编辑:我想我已经找到了使用该软件包的解决方法,但是在发布我认为有效的方法之前multiprocessing,我会留下未回答的问题,让joblib人员做出回应。

4

1 回答 1

2

这可以使用multiprocessing模块按如下方式完成:

import numpy as np
from fastdtw import fastdtw
import multiprocessing as mp
from scipy.spatial.distance import squareform, euclidean
from functools import partial

# Create simulated data matrix
data = np.random.random((33,300))

N, _ = data.shape
upper_triangle = [(i,j) for i in range(N) for j in range(i+1, N)]

with mp.Pool(processes=4) as pool:
    result = pool.starmap(partial(fastdtw, dist=euclidean), [(data[i], data[j]) for (i,j) in upper_triangle])

dist_mat = squareform([item[0] for item in result])

timeitIvyBridge Core-i5上使用的计时结果:

24.052 secs

这是没有显式并行化的一半时间。

还:

作为使用该fastdtw软件包的任何人的未来参考。如链接上的示例所示,导入距离函数scipy.spatial.distance并调用比仅使用: 慢得多。结果似乎与我相似,使用(不诉诸并行化)的执行时间不到一秒。fastdtwfastdtw(x,y,dist=2)pdist

于 2018-07-17T12:36:21.233 回答