2016-09-22 5 views
0

Привет всем Я пытаюсь написать код (используя python 2), который возвращает матрицу, которая содержит расстояние между всеми парами строк. Ниже приведена реализация, которую я написал. Он работает так, как ожидалось, но может быть очень медленным, поскольку количество строк становится большим. Поэтому мне было интересно, есть ли у кого-нибудь какие-либо предложения относительно того, как код можно сделать более эффективным для большого количества строк.Более эффективный способ вычисления матрицы расстояния в Python

Заранее спасибо

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 
+0

python 2 или python 3? –

+2

http://docs.scipy.org/doc/scipy/reference/spatial.distance.html. [Вот пример] (http://stackoverflow.com/a/39205919/5741205) – MaxU

ответ

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 для применения других показателей.

0

Без scipy (можно получить numpy без scipy, например, с установкой 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 

Это должно быть надежным, по крайней мере, это то, что я должен был использовать.