如何在计算向量之间的距离时避免由双“for循环”导致的二次计算

时间:2013-08-02 10:38:27

标签: python numpy complexity-theory distance quadratic

给出以下代码来计算列表'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] =

提前感谢您的建议。

2 个答案:

答案 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元素的长数组。