给出以下代码来计算列表'vect'中向量之间的距离:
import numpy as np
vect=([0.123, 0.345, 0.789], [0.234, 0.456, 0.567],[0.134, 0.246, 0.831])
def kn():
for j in vect:
c=np.array(j)
for z in vect:
p=np.array(z)
space = np.linalg.norm(c-p)
print space
kn()
有没有办法避免双重'for循环'导致的二次复杂度?
由于双循环(二次)= = 3X3 = 9
的计算结果Ideal computation (what I want) should be (3):
[0.123, 0.345, 0.789] and [0.234, 0.456, 0.567] =
[0.123, 0.345, 0.789] and [0.134, 0.246, 0.831] =
[0.234, 0.456, 0.567] and [0.134, 0.246, 0.831] =
提前感谢您的建议。
答案 0 :(得分:2)
为了避免重复对,嵌套循环应该从外循环的索引向上,即:
for i, v1 in enumerate(vect):
for j in xrange(i + 1, len(vect)):
a = np.array(v1)
b = np.array(vect[j])
space = np.linalg.norm(b - a)
print space
或使用标准库提供的解决方案:
import itertools
for v1, v2 in itertools.combinations(vect, 2):
a = np.array(v1)
b = np.array(v2)
space = np.linalg.norm(b - a)
print space
答案 1 :(得分:2)
其他人已经注意到你无法避免二次复杂性。但是如果你关注的是性能,你可以使用scipy.spatial.distance.pdist
来大大加快速度,这将使所有的循环和函数调用都发生在C语言中,而不是Python中。以下代码返回一个方形,对称的数组,但它只进行n *(n-1)/2
计算:
from scipy.spatial.distance import pdist
pairwise_distances = pdist(vect, metric='euclidean', p=2)
如果您想要一个只有唯一的非对角线值的扁平数组,您可以使用scipy.spatial.distance.squareform
:
from scipy.spatial.distance import pdist, squareform
pairwise_distances = squareform(pdist(vect, metric='euclidean', p=2))
在您的情况下,pairwise_distances
将是一个3元素的长数组。