Sorting points from distance to a given point x,y here in my case (x=0,y=o)

心已入冬 提交于 2019-12-02 16:44:56

问题


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 ??**

回答1:


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]])



回答2:


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]))


来源:https://stackoverflow.com/questions/46571624/sorting-points-from-distance-to-a-given-point-x-y-here-in-my-case-x-0-y-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!