Python 向量化矩阵与向量之间欧氏距离的计算

Python 向量化矩阵与向量之间欧氏距离的计算,python,multithreading,vectorization,euclidean-distance,Python,Multithreading,Vectorization,Euclidean Distance,我想计算矩阵和标准向量之间的欧几里德距离。 我所有的矩阵都存储在一个列表中,比如说,a,这样 A=[1,2,3],[2,3,4]…,[8,9,10], 标准向量是,比方说,[1,1,1], 我可以使用for循环来实现这一点,但这确实很耗时,因为一个循环中通常有数百个矩阵。 如何将此计算矢量化以缩短运行时间 A = np.array([[1,2,3], [2,3,4], [3,4,5], [4,5,6],

我想计算矩阵和标准向量之间的欧几里德距离。 我所有的矩阵都存储在一个列表中,比如说,a,这样

A=[1,2,3],[2,3,4]…,[8,9,10],

标准向量是,比方说,
[1,1,1]
,

我可以使用for循环来实现这一点,但这确实很耗时,因为一个循环中通常有数百个矩阵。 如何将此计算矢量化以缩短运行时间

A = np.array([[1,2,3],
              [2,3,4],
              [3,4,5],
              [4,5,6],
              [5,6,7],
              [6,7,8],
              [7,8,9],
              [8,9,10]])

v = np.array([1,1,1])

# Compute the length (norm) of the distance between the vectors
distance = np.linalg.norm(A - v, axis = 1)
print(distance)
方法#1

用于距离计算。为了解决我们的问题,我们可以-

def dist_matrix_vec(matrix, vec):    
    d = np.subtract(matrix,vec)
    return np.sqrt(np.einsum('ij,ij->i',d,d))
样本运行-

In [251]: A = [[1,2,3],[2,3,4],[8,9,10]]

In [252]: B = np.array([1,1,1])

In [253]: dist_matrix_vec(A,B)
Out[253]: array([ 2.23606798,  3.74165739, 13.92838828])
方法#2

在处理大数据时,如果预期的操作可以表示为算术操作,我们可以使用支持多核处理的。为了解决我们的问题,我们可以这样表达-

import numexpr as ne

def dist_matrix_vec_numexpr(matrix, vec): 
    matrix = np.asarray(matrix)
    vec = np.asarray(vec)
    return np.sqrt(ne.evaluate('sum((matrix-vec)**2,1)'))

大型阵列上的定时-

In [295]: np.random.seed(0)
     ...: A = np.random.randint(0,9,(10000,3))
     ...: B = np.random.randint(0,9,(3,))

In [296]: %timeit np.linalg.norm(A - B, axis = 1) #@Nathaniel's soln
     ...: %timeit dist_matrix_vec(A,B)
     ...: %timeit dist_matrix_vec_numexpr(A,B)
1000 loops, best of 3: 244 µs per loop
10000 loops, best of 3: 131 µs per loop
10000 loops, best of 3: 96.5 µs per loop

In [297]: np.random.seed(0)
     ...: A = np.random.randint(0,9,(100000,3))
     ...: B = np.random.randint(0,9,(3,))

In [298]: %timeit np.linalg.norm(A - B, axis = 1) #@Nathaniel's soln
     ...: %timeit dist_matrix_vec(A,B)
     ...: %timeit dist_matrix_vec_numexpr(A,B)
100 loops, best of 3: 5.31 ms per loop
1000 loops, best of 3: 1.43 ms per loop
1000 loops, best of 3: 918 µs per loop

基于
numexpr
的一个线程是
8
线程。因此,随着更多的线程可用于计算,它应该进一步改进。关于如何控制多核功能。

这是最快的方法吗?是比较不同方法速度的几个问题之一。特别是对于大型/大量矩阵,我强烈推荐
np.linalg.norm()
In [295]: np.random.seed(0)
     ...: A = np.random.randint(0,9,(10000,3))
     ...: B = np.random.randint(0,9,(3,))

In [296]: %timeit np.linalg.norm(A - B, axis = 1) #@Nathaniel's soln
     ...: %timeit dist_matrix_vec(A,B)
     ...: %timeit dist_matrix_vec_numexpr(A,B)
1000 loops, best of 3: 244 µs per loop
10000 loops, best of 3: 131 µs per loop
10000 loops, best of 3: 96.5 µs per loop

In [297]: np.random.seed(0)
     ...: A = np.random.randint(0,9,(100000,3))
     ...: B = np.random.randint(0,9,(3,))

In [298]: %timeit np.linalg.norm(A - B, axis = 1) #@Nathaniel's soln
     ...: %timeit dist_matrix_vec(A,B)
     ...: %timeit dist_matrix_vec_numexpr(A,B)
100 loops, best of 3: 5.31 ms per loop
1000 loops, best of 3: 1.43 ms per loop
1000 loops, best of 3: 918 µs per loop