在Python中计算距离矩阵的更有效方法

时间:2016-09-22 08:18:20

标签: python performance distance-matrix

大家好我正在尝试编写代码(使用python 2),它返回一个包含所有行对之间距离的矩阵。以下是我编写的实现。它按预期工作,但随着行数变大,速度会变慢。因此,我想知道是否有人建议如何使代码更有效地用于大量行。

提前致谢

def gendist(x,alpha=2):
    (n,p) = x.shape
    len = 0
    for ii in range(1,n):
        len = len + ii
    d = np.empty((len,p))
    ind = 0
    for ii in range(0,n):
        for jj in range(1,n):
            if ii < jj:
                d[ind,] = (x[ii,]-x[jj,])**alpha
                ind = ind + 1
    return d

3 个答案:

答案 0 :(得分:0)

我看到您使用X.shape,对我而言,我们假设您使用NumPy

代码:

#!/usr/bin/env python3
import numpy as np
import scipy.spatial.distance as dist

a = np.random.randint(0, 10, (5, 3))
b = dist.pdist(a)
print('Matrix:')
print(a)
print('Pdist')
for d in b:
    print(d)

输出:

Matrix:
[[4 7 6]
 [8 2 8]
 [8 3 5]
 [2 4 7]
 [0 7 5]]
Pdist
6.7082039325
5.74456264654
3.74165738677
4.12310562562
3.16227766017
6.40312423743
9.89949493661
6.40312423743
8.94427191
4.12310562562

其中组合的顺序是(0,1),(0,2),(0,3),(0,4),(1,2),(1,3),(1,4) ,(2,3),(2,4),...

默认指标是欧几里德距离。 请参阅pdist以应用其他指标。

答案 1 :(得分:0)

没有scipy(有可能在没有scipy的情况下获得numpy,例如使用Abaqus安装),这有点困难。

def gendist(x,alpha=2):
    xCopies=x.repeat(x.shape[0],axis=0).reshape(np.conatenate(([a.shape[0]],a.shape))
    #n x n x p matrix filled with copies of x
    xVecs=xCopies-xCopies.swapaxes(0,1) #matrix of distance vectors
    xDists=np.sum(xVecs**alpha,axis=-1)**(1/alpha) #n x n matrix of distances
    Return xDists

这应该是强大的,至少它是我必须使用的。

答案 2 :(得分:0)

我认为您正在寻找的是sklearn pairwise_distances。 scipy distance_matrix在我的计算机上花费了约115秒的时间来计算512维向量上的10Kx10K距离矩阵。 scipy cdist大约需要50秒。 sklearn pairwise_distances大约需要9秒。从文档中:

  

请注意,对于“ cityblock”,“ cosine”和“ euclidean”(   是有效的scipy.spatial.distance指标),scikit-learn   将使用实现,它更快,并且支持   稀疏矩阵(“ cityblock”除外)。