matrix1=dim(15,3)
和matrix2=dim(23,3)
。
例如:
matrix1=[[5,7,8],
[10,6,8],
...
...
...,
[11,14,78]]
和
matrix2=[[3,7,9],
[12,11,18],
...,
...,
[78,99,10]]
输出是什么?
matrix_distance=dim(15,23)
为了便于说明,我们只考虑第一个通道和第一行:
matrix_distance[:,:,0]=[(5-3)^2, (5-12)^2, ..., (5-78)^2]
计算它的有效和矢量化方法是什么?
EDIT1:
非矢量化解决方案
for i in np.arange(len(matrix1)):
for j in np.arange(len(matrix2)):
for channel in np.arange(matrix1[0,0,:]):
matrix_distance[i,:,p]=(matrix1[i,:,p]-matrix2[j,:,p])^2
A = [[5,7,8]]
B = [[3,7,9],[3,7,9],[78,99,10]]
然后
c=[[(5-3)^2,(7-7)^2,(8-9)^2],[(5-3)^2,(7-7)^2,(8-9)^2],[(5-78)^2,(7-99)^2,(8-10)^2]]
答案 0 :(得分:1)
使用scipy' cdist。
In [8]: cdist(matrix1,matrix2).shape
Out[8]: (15, 23)
答案 1 :(得分:1)
作为scipy的cdist的替代品,你也可以使用Numba,它可以提供更好的性能。如果满足您的精度要求,也可以考虑仅使用32位浮点数进行计算。
import numpy as np
import numba as nb
import time
from scipy.spatial.distance import cdist
#Maybe calculation with 32bit floats is sufficient?
#creating random 32bit floats
vec_1=np.array(np.random.rand(10000,3),dtype=np.float32)
vec_2=np.array(np.random.rand(20000,3),dtype=np.float32)
@nb.njit(fastmath=True,parallel=True)
def calc_distance(vec_1,vec_2):
assert vec_1.shape[1]==3 #Enable SIMD-Vectorization (adding some performance)
assert vec_2.shape[1]==3 #Enable SIMD-Vectorization (adding some performance)
res=np.empty((vec_1.shape[0],vec_2.shape[0]),dtype=vec_1.dtype)
for i in nb.prange(vec_1.shape[0]):
for j in range(vec_2.shape[0]):
res[i,j]=np.sqrt((vec_1[i,0]-vec_2[j,0])**2+(vec_1[i,1]-vec_2[j,1])**2+(vec_1[i,2]-vec_2[j,2])**2)
return res
t1=time.time()
res=calc_distance(vec_1,vec_2)
print(time.time()-t1)
t1=time.time()
A=cdist(vec_1,vec_2) #cdist approach
print(time.time()-t1)
这是一个四核i7-4.Gen 0.25s(Numba),1.3s cdist。用64位精度计算得到0.44s(Numba)。