【发布时间】:2020-10-15 20:47:12
【问题描述】:
我有一个矩阵 A 并想从它迭代计算距离矩阵 D。想要一步一步计算的原因是为了以后在迭代过程中包含一些if语句。
我现在的代码如下所示:
import numpy as np
from scipy.spatial import distance
def create_data_matrix(n,m):
mean = np.zeros(m)
cov = np.eye(m, dtype=float)
data_matrix = np.random.multivariate_normal(mean,cov,n)
return(data_matrix)
def create_full_distance(A):
distance_matrix = np.triu(distance.squareform(distance.pdist(A,"euclidean")),0)
return(distance_matrix)
matrix_a = create_data_matrix(1000,2)
distance_from_numpy = create_full_distance(matrix_a)
matrix_b = np.empty((1000,1000))
for idx, line in enumerate(matrix_a):
for j, line2 in enumerate(matrix_a):
matrix_b[idx][j] = distance.euclidean(matrix_a[idx],matrix_a[j])
现在矩阵 "distance_from_numpy" 和 "matrix_b" 是相同的,尽管 matrix_b 需要更长的时间来计算尽管 matrix_a 只是一个 (100x2) 矩阵,而且我知道 "distance.pdist()" 方法非常快但我不确定是否可以在迭代过程中实现它。
我的问题是,为什么双 for 循环这么慢,我怎样才能提高速度,同时仍然保留迭代过程(因为我想在那里包含 if 语句)?
编辑:对于上下文:我想保留迭代,因为如果其中一个距离小于特定数字,我想停止迭代。
【问题讨论】:
-
你的矩阵有多大?如果是 100x2,使用 np.linalg.norm 计算所有距离然后检查阈值可能会更快。
-
现在的数据矩阵是 100x2,但在某些时候我会有一个 (100000x1000) 数据矩阵。所以相应的距离矩阵将是 100x100 和 100000x100000
-
这是相当大的。对
distance.euclidean的调用可能需要足够长的时间,因此Python for 循环不再重要。我建议你先比较distance_from_numpy和matrix_b的时间,比如 (100x1000)。 -
在上面给出的例子中,计算速度的差异是“感觉的”,因为 numpy 创建的全距离矩阵“distance_from_numpy”是立即计算的,而 for 循环创建的距离矩阵“matrix_b”需要一秒钟或两个都只有 1000x1000
-
这是相当大的。尝试 numba 并自己计算距离。
标签: python-3.x performance numpy matrix iteration