Python 如何计算点列表中从一个点到另一个点的相对向量
我有一个Python 如何计算点列表中从一个点到另一个点的相对向量,python,arrays,numpy,Python,Arrays,Numpy,我有一个(x,y)对中的点列表,它表示代理列表的位置。例如,给定3个代理,有3对点,我存储如下: points = np.array([[x1, y1], [x2, y2], [x3, y3]]) 我想计算一个后续数组,即从一个代理到每个其他代理的相对位置,但不是它本身。因此,使用上面的数据,我想使用数组点生成数组相对位置点可以有N位置(我可以在任何时候拥有50-100个以上的代理) 因此,使用上面描述的点,我想生成输
(x,y)
对中的点列表,它表示代理列表的位置。例如,给定3个代理,有3对点,我存储如下:
points = np.array([[x1, y1],
[x2, y2],
[x3, y3]])
我想计算一个后续数组,即从一个代理到每个其他代理的相对位置,但不是它本身。因此,使用上面的数据,我想使用数组点
生成数组相对位置
<代码>点可以有N
位置(我可以在任何时候拥有50-100个以上的代理)
因此,使用上面描述的点
,我想生成输出:
relative_positions = [[x2-x1, y2-y1],
[x3-x1, y3-y1],
[x1-x2, y1-y2],
[x3-x2, y3-y2],
[x1-x3, y1-y3],
[x2-x3, y2-y3]]
relative_positions = [[30-10, 3-1],
[25-10, 10-1],
[5-10, 5-1],
[10-30, 1-3],
[25-30, 10-3],
[5-30, 5-3],
[10-25, 1-10],
[30-25, 3-10],
[5-25, 5-10],
[10-5, 1-5],
[30-5, 3-5],
[25-5, 10-5]]
例如,给定存储为numpy数组的四个代理位置:
agent_points = np.array([[10, 1],
[30, 3],
[25, 10],
[5, 5]])
我想生成输出:
relative_positions = [[x2-x1, y2-y1],
[x3-x1, y3-y1],
[x1-x2, y1-y2],
[x3-x2, y3-y2],
[x1-x3, y1-y3],
[x2-x3, y2-y3]]
relative_positions = [[30-10, 3-1],
[25-10, 10-1],
[5-10, 5-1],
[10-30, 1-3],
[25-30, 10-3],
[5-30, 5-3],
[10-25, 1-10],
[30-25, 3-10],
[5-25, 5-10],
[10-5, 1-5],
[30-5, 3-5],
[25-5, 10-5]]
我如何有效地进行这项工作?我考虑过只计算每个可能的差异,并删除0个案例(当它是代理到自身的相对位置时),但我不认为这是一种“纯粹”的方法,因为我可能会意外删除恰好位于同一点(或非常接近)的代理虽然我没有特定于numpy的解决方案(我确信它存在),但双for循环和id检查可以很好地解决这个问题。但是,如果
点数增加,则需要一些时间
点=[
[x1,y1],
[x2,y2],
[x3,y3]
]
相对位置=[]
对于点中的点1:
对于点2中的点:
如果id(第1点)!=id(第2点):
相对位置。追加([CALC\u此处\u或\u函数])
方法#1
使用a
输入数组,您可以-
d = (a-a[:,None,:])
valid_mask = ~np.eye(len(a),dtype=bool)
out = d[valid_mask]
基本上,我们将a
扩展到3D
,使得第一个轴可以外部广播
,然后我们对其2D
版本执行减法,从而产生mxmx2
成形输出,m
为a.shape[0]
。示意性地放-
a[:, None, :] : 4 x 1 x 2
a : 4 x 2
output : 4 x 4 x 2
另一种创建有效屏蔽的方法是-
r = np.arange(len(a))
valid_mask = r[:,None] != r
d = (a-a[:,None,:])
out = nodiag_view3D(d).reshape(-1,a.shape[1])
方法#2
我们将利用np.lib.stride\u技巧.as\u stride
为3D
数组(沿前两个轴)获得一个非对角掩码,以便在这里使用它来掩盖数组d
的差异。此蒙版生成的灵感来自于发布的2D
阵列问题,对于3D
案例,其外观如下所示-
def nodiag_view3D(a):
m = a.shape[0]
p,q,r = a.strides
return np.lib.stride_tricks.as_strided(a[:,1:], shape=(m-1,m,2), strides=(p+q,q,r))
要解决我们的问题,它将是-
r = np.arange(len(a))
valid_mask = r[:,None] != r
d = (a-a[:,None,:])
out = nodiag_view3D(d).reshape(-1,a.shape[1])
展示方法2如何改进方法1的时间安排
谢谢,我已经考虑过这个选项,但是我可能正在寻找numpy特定的解决方案,因为我关心速度(这个计算可以在每幕100k-10M次之间执行)。这是一个非常优雅的解决方案。我了解大部分正在发生的事情,你能解释一下a[:,None,:]
在这种情况下会发生什么?@Athena添加了一些评论。