Ordenar puntos desde la distancia hasta un punto dado x, y aquí en mi caso (x = 0, y = o)

Me gustaría ordenar (de más corto a más largo) una matriz ‘a’ (como se indica a continuación) a la distancia desde el origen o un punto (en mi caso, 0,0) y almacenarla en una matriz similar tipo ‘b’ o reemplazarla la matriz ‘a’

los puntos dados a continuación son 3d numpy array

[[[ 510. 11.]] [[ 651. 276.]] [[ 269. 70.]] [[ 920. 26.]] [[ 513. 21.]] [[ 1197. 620.]] [[ 407. 268.]] [[ 452. 35.]] [[ 435. 3.]] [[ 520. 20.]] [[ 1151. 499.]] [[ 104. 26.]] [[ 754. 28.]] [[ 263. 111.]] [[ 731. 12.]] [[ 972. 200.]] [[ 1186. 614.]] [[ 437. 2.]] [[ 1096. 68.]] [[ 997. 201.]] [[ 1087. 200.]] [[ 913. 201.]] [[ 1156. 510.]] [[ 994. 230.]] [[ 793. 29.]] [[ 514. 19.]]] 

No puedo encontrar ninguna información útil con respecto a este tipo de ordenación de matrices 3d np

ps: Estos puntos ‘a’ se obtuvieron de Goodfeaturesttrack, OPEN CV, python 3.6

¿Y cómo se borra una matriz de tipo nulo?

  #this is clustering algorithm for index in range(len(a): #a is the above matrix 3d np array #find distance was already defined and is euclidean distance formula if findDistance(a[index][0], a[index][1], a[index + 1][0], a[index + 1][1])  3: #calculation euclidean distance between ai and ai+1 if len(c) > 10: cp = np.insert(cp, c, 0) c = [] # should clear c **is this correct ??** 

Me gusta tener esto a mano para calcular distancias en varios formatos de matriz … no es de una sola línea, pero funciona. Los detalles sobre sus implementaciones se pueden encontrar en otra parte en la stack buscando ‘einsum’ y numpy como palabras clave. Importa números como np requerido, esta es solo la definición y necesitas 2 arreglos

 import numpy as np def e_dist(a, b, metric='euclidean'): """Distance calculation for 1D, 2D and 3D points using einsum : a, b - list, tuple, array in 1,2 or 3D form : metric - euclidean ('e','eu'...), sqeuclidean ('s','sq'...), :----------------------------------------------------------------------- """ a = np.asarray(a) b = np.atleast_2d(b) a_dim = a.ndim b_dim = b.ndim if a_dim == 1: a = a.reshape(1, 1, a.shape[0]) if a_dim >= 2: a = a.reshape(np.prod(a.shape[:-1]), 1, a.shape[-1]) if b_dim > 2: b = b.reshape(np.prod(b.shape[:-1]), b.shape[-1]) diff = a - b dist_arr = np.einsum('ijk,ijk->ij', diff, diff) if metric[:1] == 'e': dist_arr = np.sqrt(dist_arr) dist_arr = np.squeeze(dist_arr) return dist_arr 

Luego puede ordenar el resultado si es necesario, por ejemplo

 a = np.random.randint(0, 10, size=(10,2)) orig = np.array([0,0]) e_dist(a, orig) array([ 4.12, 9.9 , 7.07, 6.08, 3.16, 10.63, 8.54, 7.28, 7.21, 6.08]) np.sort(e_dist(a, orig)) array([ 3.16, 4.12, 6.08, 6.08, 7.07, 7.21, 7.28, 8.54, 9.9 , 10.63]) 

APÉNDICE

Debería haber agregado que puede obtener los valores ordenados utilizando argsort como se ilustra a continuación.

 np.argsort(e_dist(a, orig)) array([4, 0, 3, 9, 2, 8, 7, 6, 1, 5], dtype=int64) idx = np.argsort(art.e_dist(a, orig)) closest = a[idx] array([[3, 1], [1, 4], [1, 6], [6, 1], [5, 5], [4, 6], [2, 7], [8, 3], [7, 7], [7, 8]]) 
 def distance_squared(x1,y1,x2,y2): return (x1-x2)**2 + (y1-y2)**2 target_point = 0,0 sorted(a,key=lambda point:distance_squared(target_point[0],target_point[1],*point[0]))