I would like to sort (shortest to longest) an array 'a' (as given below) to the distance from the origin or a point (in my case 0,0) and store it to a similar array type 'b' or replacing the array 'a'
the below given points are 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.]]]
I cannot find any helpful information regarding these kind of 3d np arrays sorting
ps: These points 'a' were obtained from Goodfeaturestotrack ,OPEN CV ,python 3.6
and how do you clear an array to Null type ?
#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
c.append(index)
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 ??**
I like to keep this handy to calculate distances in several array formats... it isn't a one-liner, but it works. Details on its implementations can be found elsewhere on stack by searching for 'einsum' and numpy as keywords. Import numpy as np required, this is just the def and you need 2 arrays
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
Then you can sort the result if needed, for example
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])
ADDENDUM
I should have added that you can get the sorted values using argsort as exemplified below
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]])