Distância espacial vetorizada em python usando numpy

Eu tenho uma matriz numpy em python que contém lotes (10k +) de pontos de vértice 3D (vetores com coordenadas [x, y, z]). Preciso calcular a distância entre todos os pares possíveis desses pontos.

é fácil fazer isso usando o scipy:

import scipy
D = spdist.cdist(verts, verts)

mas não posso usar isso por causa da política do projeto de introdução de novas dependências.

Então, eu vim com este código ingênuo:

def vert_dist(self, A, B):
    return ((B[0]-A[0])**2+(B[1]-A[1])**2+(B[2]-A[2])**2)**(1.0/2)

# Pairwise distance between verts
#Use SciPy, otherwise use fallback
try:
    import scipy.spatial.distance as spdist
    D = spdist.cdist(verts, verts)
except ImportError:
    #FIXME: This is VERY SLOW:
    D = np.empty((len(verts), len(verts)), dtype=np.float64)
    for i,v in enumerate(verts):
        #self.app.setStatus(_("Calculating distance %d of %d (SciPy not installed => using SLOW AF fallback method)"%(i,len(verts))), True)
        for j in range(i,len(verts)):
            D[j][i] = D[i][j] = self.vert_dist(v,verts[j])

vert_dist () calcula a distância 3D entre dois vértices e o restante do código apenas itera sobre os vértices na matriz 1D e para cada uma calcula a distância entre si na mesma matriz e produz uma matriz 2D de distâncias.

Mas isso é extremamente lento (1000 vezes) quando comparado ao código C nativo do scipy. Gostaria de saber se posso acelerar usando numpy puro. pelo menos até certo ponto.

Mais algumas informações:https://github.com/scipy/scipy/issues/9172

BTW eu tentei o compilador PyPy JIT e foi ainda mais lento (10 vezes) do que puro python.

UPDATE: Eu fui capaz de acelerar as coisas um pouco assim:

    def vert_dist_matrix(self, verts):
            #FIXME: This is VERY SLOW:
            D = np.empty((len(verts), len(verts)), dtype=np.float64)
            for i,v in enumerate(verts):
                    D[i] = D[:,i] = np.sqrt(np.sum(np.square(verts-verts[i]), axis=1))
            return D

Isso elimina o loop interno, computando toda a linha de uma só vez, o que torna as coisas muito mais rápidas, mas ainda visivelmente mais lentas que as escorregadias. Então, continuo vendo a solução da @ Divakar

questionAnswers(2)

yourAnswerToTheQuestion