Python 按到参考点的距离对多个D点的数组进行排序

Python 按到参考点的距离对多个D点的数组进行排序,python,numpy,sorting,multidimensional-array,distance,Python,Numpy,Sorting,Multidimensional Array,Distance,我有一个参考点p_ref存储在一个形状为(1024,)的numpy数组中,类似于: print(p_ref) >>> array([ p1, p2, p3, ..., p_n]) 我还有一个numpy数组a_points,形状为(10245000),包含5000个点,每个点有1024个维度,如p_ref。我的问题:我想按点到p\u ref的(欧氏)距离对A\u点中的点进行排序 我该怎么做?我读到了关于scipy.spatial.distance.cdist和scipy.s

我有一个参考点
p_ref
存储在一个形状为(1024,)的numpy数组中,类似于:

print(p_ref)
>>> array([ p1,  p2,  p3, ..., p_n])
我还有一个numpy数组
a_points
,形状为(10245000),包含5000个点,每个点有1024个维度,如
p_ref
。我的问题:我想按点到
p\u ref
的(欧氏)距离对
A\u点中的点进行排序

我该怎么做?我读到了关于scipy.spatial.distance.cdist和scipy.spatial.KDTree的文章,但是他们都没有完全按照我的要求去做,当我试图将它们组合起来时,我把它们搞得一团糟。谢谢


为了便于参考和一致性,我们假设:

p_ref = np.array([0,1,2,3])
A_points = np.reshape(np.array([10,3,2,13,4,5,16,3,8,19,4,11]), (4,3))
预期产出:

array([[ 3,  2, 10],
       [ 4,  5, 13],
       [ 3,  8, 16],
       [ 4, 11, 19]])

编辑:根据OP的建议进行更新

我希望我能正确地理解你,但是你可以使用下列公式计算两个向量之间的距离。使用此选项应简单到:

A_sorted = sorted( A_points.T, key = lambda x: np.linalg.norm(x - p_ref ) )
A_sorted = np.reshape(A_sorted, (3,4)).T

编辑:根据OP的建议进行更新

我希望我能正确地理解你,但是你可以使用下列公式计算两个向量之间的距离。使用此选项应简单到:

A_sorted = sorted( A_points.T, key = lambda x: np.linalg.norm(x - p_ref ) )
A_sorted = np.reshape(A_sorted, (3,4)).T

你可以这样做-

A_points[:,np.linalg.norm(A_points-p_ref[:,None],axis=0).argsort()]
另一个带有
np.einsum
的,应该比
np.linalg.norm
-

d = A_points-p_ref[:,None]
out = A_points[:,np.einsum('ij,ij->j',d,d).argsort()]
进一步优化,以利用快速矩阵乘法替换最后一步-

A_points[:,((A_points**2).sum(0)+(p_ref**2).sum()-2*p_ref.dot(A_points)).argsort()]

你可以这样做-

A_points[:,np.linalg.norm(A_points-p_ref[:,None],axis=0).argsort()]
另一个带有
np.einsum
的,应该比
np.linalg.norm
-

d = A_points-p_ref[:,None]
out = A_points[:,np.einsum('ij,ij->j',d,d).argsort()]
进一步优化,以利用快速矩阵乘法替换最后一步-

A_points[:,((A_points**2).sum(0)+(p_ref**2).sum()-2*p_ref.dot(A_points)).argsort()]

谢谢第一个建议很好,但要使其发挥作用,我必须将A_点转置
A_点
并去掉
[:,None]
,最终得到
A_out=A_点.T[np.linalg.norm(A_点.T-p_参考,axis=1).argsort()
。如果你在意,你可以编辑你的答案。你也可以用这些玩具值进行测试,它们与我在帖子中的维度一致:
p_ref=np.array([0,1,2,3])
A_points=np.restrape(np.array([10,3,2,13,4,5,16,3,8,19,4,11]),(4,3))
。第二个建议在尺寸方面也有问题,但我让它适用于
dim(A)=(4,4)
,如果您愿意,也可以更改它。@NeStack确定吗?这两个对我来说都很好。是什么让你得出这些都不起作用的结论?再次感谢你的回答!我只是按照你在玩具值上呈现它们的方式测试了你的代码片段,它们没有进行所需的计算,尽管它们运行时没有出现错误(注意dim(p_ref)=n,dim(A_points)=(n,m),为了让问题更清楚,我还将玩具值包括在问题中)。尽管如此,我只需要旋转变量就可以使它们工作,所以+1。@NeStack所以,我想你的意思是对每行
A_点进行排序。这就是困惑。代码已编辑。谢谢!第一个建议很好,但要使其发挥作用,我必须将A_点转置
A_点
并去掉
[:,None]
,最终得到
A_out=A_点.T[np.linalg.norm(A_点.T-p_参考,axis=1).argsort()
。如果你在意,你可以编辑你的答案。你也可以用这些玩具值进行测试,它们与我在帖子中的维度一致:
p_ref=np.array([0,1,2,3])
A_points=np.restrape(np.array([10,3,2,13,4,5,16,3,8,19,4,11]),(4,3))
。第二个建议在尺寸方面也有问题,但我让它适用于
dim(A)=(4,4)
,如果您愿意,也可以更改它。@NeStack确定吗?这两个对我来说都很好。是什么让你得出这些都不起作用的结论?再次感谢你的回答!我只是按照你在玩具值上呈现它们的方式测试了你的代码片段,它们没有进行所需的计算,尽管它们运行时没有出现错误(注意dim(p_ref)=n,dim(A_points)=(n,m),为了让问题更清楚,我还将玩具值包括在问题中)。尽管如此,我只需要旋转变量就可以使它们工作,所以+1。@NeStack所以,我想你的意思是对每行
A_点进行排序。这就是困惑。代码编辑。谢谢,我喜欢简单的答案,虽然其他方法可能更快!为了让它工作,我必须将A_点转置,并最终改变答案的形状,如下所示:
A_排序=排序(A_点.T,key=lambda x:np.linalg.norm(x-p_ref))
A_排序=np.reforme(A_排序,(3,4)).T
。我接受你的帖子作为答案,但是如果你想按照建议编辑它,我也在我的初始问题中提供了玩具值谢谢,我喜欢答案的简单性,尽管其他方法可能更快!为了让它工作,我必须将A_点转置,并最终改变答案的形状,如下所示:
A_排序=排序(A_点.T,key=lambda x:np.linalg.norm(x-p_ref))
A_排序=np.reforme(A_排序,(3,4)).T
。我接受你的帖子作为答案,但是如果你想按照建议编辑它,我也在我的初始问题中提供了玩具值。你能为玩具示例添加预期的输出吗?我假设输出只是一个不同的行顺序,
a_points
@Divakar当然,我添加了它:)您还可以为玩具示例添加预期的输出吗?我假设输出只是一个不同的行顺序,
a_points
@Divakar当然,我添加了它:)