Acabo de empezar a usar scipy/numpy. Tengo una matriz de 100000 * 3, cada fila es una coordenada y un punto central de 1 * 3. Quiero calcular la distancia para cada fila en el conjunto al centro y almacenarlos en otro conjunto. ¿Cuál es la forma más eficiente de hacerlo?Cálculo de distancia eficiente entre N puntos y una referencia en numpy/scipy
Respuesta
Me gustaría echar un vistazo a scipy.spatial.distance.cdist
:
http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html
import numpy as np
import scipy
a = np.random.normal(size=(10,3))
b = np.random.normal(size=(1,3))
dist = scipy.spatial.distance.cdist(a,b) # pick the appropriate distance metric
dist
para la métrica de distancia predeterminado es equivalente a:
np.sqrt(np.sum((a-b)**2,axis=1))
aunque cdist
es mucho más eficiente para grandes conjuntos (En mi máquina para su problema de tamaño, cdist
es más rápido por un factor de ~ 35x).
Puede que necesite especificar de una manera más detallada la función de distancia que le interesa, pero aquí hay una implementación muy simple (y eficiente) de Squared Euclidean Distance basada en inner product
(que obviamente puede ser generalizada, de manera directa, a otro tipo de distancia): medidas
In []: P, c= randn(5, 3), randn(1, 3)
In []: dot(((P- c)** 2), ones(3))
Out[]: array([ 8.80512, 4.61693, 2.6002, 3.3293, 12.41800])
Dónde P
son sus puntos y c
es el centro.
En mi máquina, esto sigue siendo 18 veces más lento que 'cdist' para el tamaño del problema del OP. – JoshAdel
@JoshAdel: Esa es la gran diferencia. FWIW, con 'numpy' 1.6 en mi modesta máquina: para' n' = 1e5, el tiempo s son 'cdist' 3.5 ms y' dot' 9.5 ms. Entonces 'dot' solo es 3 veces más lento. Sin embargo, con 'n' (<2e3) 'punto' mucho más pequeño será más rápido. Gracias – eat
También puede usar el desarrollo de la norma (similar a las identidades notables). Esta es probablemente la forma más eficiente de calcular la distancia de una matriz de puntos.
Aquí hay un fragmento de código que utilicé originalmente para una implementación de k-Nearest-Neighbors, en Octave, pero puedes adaptarlo fácilmente a numpy ya que solo usa multiplicaciones de matrices (el equivalente es numpy.dot()):
% Computing the euclidian distance between each known point (Xapp) and unknown points (Xtest)
% Note: we use the development of the norm just like a remarkable identity:
% ||x1 - x2||^2 = ||x1||^2 + ||x2||^2 - 2*<x1,x2>
[napp, d] = size(Xapp);
[ntest, d] = size(Xtest);
A = sum(Xapp.^2, 2);
A = repmat(A, 1, ntest);
B = sum(Xtest.^2, 2);
B = repmat(B', napp, 1);
C = Xapp*Xtest';
dist = A+B-2.*C;
Utilizaría la implementación de sklearn de la distancia euclidiana. La ventaja es el uso de la expresión más eficiente mediante el uso de la multiplicación de matrices:
dist(x, y) = sqrt(dot(x, x) - 2 * dot(x, y) + dot(y, y)
Un simple script se vería así:
import numpy as np
x = np.random.rand(1000, 3)
y = np.random.rand(1000, 3)
dist = np.sqrt(np.dot(x, x)) - (dot(x, y) + dot(x, y)) + dot(y, y)
La ventaja de este enfoque ha sido muy bien descrito en la documentación sklearn : http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.euclidean_distances.html#sklearn.metrics.pairwise.euclidean_distances
Estoy usando este enfoque para procesar las grandes matrices de datos (10000, 10000) con algunas modificaciones menores como usar la función np.einsum.
Esto podría no responder su pregunta directamente, pero si lo es después de todas las permutaciones de pares de partículas, en algunos casos he encontrado que la siguiente solución es más rápida que la función pdist.
import numpy as np
L = 100 # simulation box dimension
N = 100 # Number of particles
dim = 2 # Dimensions
# Generate random positions of particles
r = (np.random.random(size=(N,dim))-0.5)*L
# uti is a list of two (1-D) numpy arrays
# containing the indices of the upper triangular matrix
uti = np.triu_indices(100,k=1) # k=1 eliminates diagonal indices
# uti[0] is i, and uti[1] is j from the previous example
dr = r[uti[0]] - r[uti[1]] # computes differences between particle positions
D = np.sqrt(np.sum(dr*dr, axis=1)) # computes distances; D is a 4950 x 1 np array
Ver this para una mirada más a fondo sobre este asunto, en mi blog.
- 1. Cálculo de la distancia entre dos puntos
- 2. Manera eficiente de encontrar la distancia entre dos puntos 3D
- 3. Cálculo de todas las distancias entre un punto y un grupo de puntos de manera eficiente en R
- 4. Obtener la distancia entre dos puntos geográficos
- 5. Distancia entre dos lat, lon puntos
- 6. Diferencia de distancia entre dos puntos en iOS y Android
- 7. ¿Cómo encuentro la distancia entre dos puntos?
- 8. la distancia entre dos puntos Android
- 9. distanceFromLocation - Calcular la distancia entre dos puntos
- 10. Encontrar la distancia entre CLLocationCoordinate2D puntos
- 11. Cálculo de una curva cuádruple entre dos puntos xy
- 12. Algoritmo para calcular una distancia entre 2 puntos tridimensionales?
- 13. Cálculo de distancia usando una sola cámara
- 14. la distancia más corta entre dos puntos (conjunto disjunto)
- 15. paralelo código C para cálculo de distancia
- 16. Encontrar la distancia máxima entre (x, y) coordenadas
- 17. ¿Cómo usar OpenStreetMap para obtener distancia entre dos puntos?
- 18. ¿Cómo puedo calcular la distancia entre dos puntos en MkMapview?
- 19. Java: Diferencia entre los puntos de referencia micro y micro
- 20. C++ Cálculo eficiente de una media móvil
- 21. python numpy euclidean cálculo de distancia entre matrices de vectores de fila
- 22. Optimización de una función de cálculo de distancia
- 23. Medir la distancia entre dos puntos Lat/Lng
- 24. OpenLayers: ¿Cómo calcular la distancia entre dos puntos?
- 25. Encontrar puntos en una línea con una distancia dada
- 26. Cálculo del cuadro delimitador a cierta distancia de una coordenada lat/long en Java
- 27. Cálculo de distancia dentro de un edificio
- 28. ¿Cómo puedo obtener la distancia entre dos puntos latlng?
- 29. Cálculo de expresiones módulo n
- 30. Cálculo de distancia geoespacial con radianes
posible duplicado de [calcule la distancia euclidiana con numpy] (http: // stackoverflow.com/questions/1401712/calculate-euclidean-distance-with-numpy) –
@larsmans: No creo que sea un duplicado ya que las respuestas solo se refieren a la distancia entre dos puntos más que a la distancia entre N puntos y un punto de referencia . Y ciertamente las respuestas no apuntan al OP a la solución scipy eficiente que muestro a continuación. – JoshAdel
@JoshAdel: vale, es suficiente. –