Ho appena iniziato a usare scipy/numpy. Ho una matrice 100000 * 3, ogni riga è una coordinata e un punto centrale 1 * 3. Voglio calcolare la distanza per ogni riga dell'array al centro e memorizzarla in un altro array. Qual è il modo più efficiente per farlo?Calcolo della distanza efficiente tra N punti e un riferimento in numpy/scipy
risposta
vorrei dare un'occhiata 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
per la metrica lontana predefinita è equivalente a:
np.sqrt(np.sum((a-b)**2,axis=1))
anche se cdist
è molto più efficiente per grandi array (sulla mia macchina per il tuo problema di dimensioni, cdist
è più veloce di un fattore di ~ 35x).
Potrebbe essere necessario specificare in modo più dettagliato la funzione di distanza a cui sei interessato, ma qui è un'implementazione molto semplice (ed efficiente) di Squared Euclidean Distance basata su inner product
(che ovviamente può essere generalizzata, modo semplice, per altri tipi di distanza misure):
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])
Dove P
sono i vostri punti e c
è il centro.
Sulla mia macchina questo è ancora 18 volte più lento di 'cdist' per la dimensione del problema dell'OP. – JoshAdel
@JoshAdel: questa è una grande differenza. FWIW, con 'numpy' 1.6 nella mia macchina modesta: per' n' = 1e5, i tempi s sono 'cdist' 3,5 ms e' punto' 9,5 ms. Quindi 'punto' è solo 3 volte più lento. Tuttavia con 'n' molto più piccolo (<2e3) 'punto' sarà più veloce. Grazie – eat
È inoltre possibile utilizzare lo sviluppo della norma (simile a identità notevoli). Questo è probabilmente il modo più efficace per calcolare la distanza di una matrice di punti.
Ecco uno snippet di codice che ho utilizzato originariamente per un'implementazione k-Nearest-Neighbors, in Octave, ma è possibile adattarlo facilmente a numpy poiché utilizza solo moltiplicazioni di matrice (l'equivalente è 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;
Vorrei utilizzare l'implementazione sklearn della distanza euclidea. Il vantaggio è l'uso dell'espressione più efficiente utilizzando moltiplicazione di matrici:
dist(x, y) = sqrt(dot(x, x) - 2 * dot(x, y) + dot(y, y)
Un semplice script sarebbe simile a questa:
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)
Il vantaggio di questo approccio è stato ben descritto nella documentazione sklearn : http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.euclidean_distances.html#sklearn.metrics.pairwise.euclidean_distances
Sto utilizzando questo approccio per il crunch di grandi datamatrices (10000, 10000) con alcune modifiche minori come l'utilizzo della funzione np.einsum.
Questo potrebbe non rispondere alla domanda direttamente, ma se si è dopo tutte le permutazioni di coppie di particelle, ho trovato la seguente soluzione per essere più veloce della funzione pdist in alcuni casi.
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
Vedi this per uno sguardo più approfondito su questo tema, nel mio blog.
- 1. Calcolo della distanza tra due punti (latitudine, longitudine)
- 2. Ricerca della distanza tra CLLocationCoordinate2D punti
- 3. Calcolo efficace di tutte le distanze tra un punto e un gruppo di punti in R
- 4. Calcolo della distanza di tutti i punti di una regione tra loro
- 5. Ottieni la distanza tra due punti geografici
- 6. Calcolo della distanza all'interno di un edificio
- 7. Calcolo della distanza di latitudine/longitudine
- 8. Calcolo distanza PostGis
- 9. Distanza tra coppie di punti su un piano cartesiano
- 10. Misurazione della distanza tra due punti Lat/Lng
- 11. Calcolo distanza tra due località geografiche
- 12. MongoDB stampa la distanza tra due punti
- 13. Calcolo della matrice fondamentale senza corrispondenza tra punti?
- 14. Calcolo della distanza da RSSI BLE android
- 15. Calcolo della distanza utilizzando una singola telecamera
- 16. Distanza diversa tra due punti su iOS e Android
- 17. Calcolo efficiente della deviazione standard cumulativa della matrice in
- 18. Calcolo della distanza di Hamming per due vettori in R?
- 19. metodo ottimizzato per il calcolo della distanza coseno in Python
- 20. Come posso calcolare la distanza tra due punti in MkMapview?
- 21. Pandas Calcolo VWAP efficiente
- 22. Calcolo della matrice di distanza euclidea utilizzando un oggetto big.matrix
- 23. calcolo della distanza di matrici di rotazione e traslazione di 2 oggetti sullo stesso piano
- 24. Come ottenere la distanza tra due punti in Android?
- 25. Calcola la distanza in (x, y) tra due punti GPS
- 26. Calcolo della distanza tra la posizione dell'utente e una posizione fissa
- 27. Come calcolare la distanza tra più punti in SQL Server?
- 28. R/ImageJ: misurazione della distanza più breve tra punti e curve
- 29. <random> uniform_real_distribution con distanza minima tra i punti
- 30. Ottimizzazione di una funzione di calcolo della distanza
possibile duplicato di [calcolare distanza euclidea con numpy] (http: // stackoverflow.it/questions/1401712/calculate-euclidean-distance-with-numpy) –
@larsmans: Non penso che sia un duplicato in quanto le risposte riguardano solo la distanza tra due punti piuttosto che la distanza tra N punti e un punto di riferimento . E certamente le risposte non indicano l'OP all'efficiente soluzione scipy che mostro di seguito. – JoshAdel
@JoshAdel: ok, abbastanza giusto. –