Plus rapide par paires distance métrique en python

J'ai un 1D tableau de nombres, et que vous voulez calculer toutes les distances euclidiennes. J'ai une méthode de (grâce à) de le faire avec de la radiodiffusion, mais il est inefficace parce qu'il calcule la distance deux fois. Et il n'est pas à l'échelle.

Voici un exemple qui me donne ce que je veux avec un tableau de 1000 numéros.

import numpy as np
import random
r = np.array([random.randrange(1, 1000) for _ in range(0, 1000)])
dists = np.abs(r - r[:, None])

Quelle est la manière la plus rapide de mise en œuvre dans scipy/numpy/scikit-learn que je peux utiliser, pour ce faire, étant donné qu'elle a pour s'adapter à des situations où les 1D tableau a >10k valeurs.

Remarque: la matrice est symétrique, donc je suppose qu'il est possible d'obtenir au moins un 2x speedup par l'aborder, je ne sais juste pas comment.

Il y a une fonction pour ça: scipy.spatial.distance.pdist. Je ne sais pas si c'est l'option la plus rapide, car il a besoin d'avoir des contrôles pour les données multidimensionnelles, non-Euclidienne normes, et d'autres choses, mais il est intégré.
Combien de temps il vous faut pour cela être? Il ne va jamais à l'échelle de mieux que O(n^2), puisque vous avez à remplir n^2 entrées de sortie. Votre solution existante est O(n^2), et il ne semble pas beaucoup de place pour les principales optimisations.
Cela semble échelle >10k valeurs assez bien déjà quand je l'ai essayer. N'oubliez pas que vous devez remplir à 100 millions d'entrées de sortie. C'est presque la moitié d'un gigaoctet de paires distances.
Je ne le pense pas... Si vous suivez le code source, à la fin, ceci est la fonction qui est appelé. Non seulement il n'y a pas de fantaisie, d'optimisation, mais pour 1D vecteurs c'est la quadrature et en prenant la racine carrée de calculer la valeur absolue. Probablement pire que l'OP du code pour son cas d'utilisation particulier.
Si je ne me trompe pas, scipy est toujours compilé avec BLAS, c'est pas une option comme avec numpy.

OriginalL'auteur roblanf | 2013-11-29