kev*_*aks 6 python arrays sorting proximity
我需要通过增加与另一个点的距离来对一个 numpy 点数组进行排序。
import numpy as np
def dist(i,j,ip,jp):
return np.sqrt((i-ip)**2+(j-jp)**2)
arr = np.array([[0,0],[1,2],[4,1]])
Run Code Online (Sandbox Code Playgroud)
我想做的是在固定点 [i,j]=[1,1] 和 arr 中的每个有序对 [ip,jp] 之间使用函数 dist(1,1,ip,jp) 来返回每个元素从最低到最高排序到 [i,j]。任何人都有一个快速的解决方案?
我想要的输出是 new_arr = np.array([[1,2],[0,0],[4,1]])
我有一些想法,但它们看起来效率极低。
谢谢!
似乎有两种方法可以做到这一点:
将整个 numpy 数组转换为 Python 列表,并使用 Python 的 sort 方法和 key 函数对其进行排序。
l = list(arr)
l.sort(key=lambda coord: dist(1, 1, coord[0], coord[1]))
arr = np.array(l)
Run Code Online (Sandbox Code Playgroud)
通过映射dist()
原始数组创建第二个 numpy 数组,用于.argsort()
获取排序顺序,然后将其应用于原始数组。
arr2 = np.vectorize(lambda coord: dist(1, 1, coord[0], coord[1]))(arr)
arr3 = np.argsort(arr2)
arr = np.array(arr)[arr3]
Run Code Online (Sandbox Code Playgroud)
我现在意识到这是一个流行的问题,所以多年后,这是我自己的答案,它使用了极其强大的功能scipy.spatial
。这里,scipy.spatial.cdist
用于进行距离计算。这是闪电般的速度和Python风格,没有任何“转换为列表并转换回来”的黑客行为:
from scipy.spatial.distance import cdist
import numpy as np
# EXAMPLE DATA
arr = 20*np.random.random(size=(5000000,2))-10 # testing data
pt = np.array([[1,1]]) # the point to eval proximity to
# THE SOLUTION
out = arr[np.argsort(cdist(arr,pt).squeeze())]
Run Code Online (Sandbox Code Playgroud)
在这里,cdist
获取一个距离数组,squeeze
删除该数组中的额外维度,argsort
按距离对距离中的索引进行排序,并按这些索引arr[...]
进行排序arr
。