我有(x,y)
对中的点列表,它表示代理列表的位置。例如,给定3个代理,有3对点,我将其存储如下:
points = np.array([[x1, y1],
[x2, y2],
[x3, y3]])
我想计算一个后续数组,即从一个代理到其他代理的相对位置,而不是它本身。因此,使用以上数据,我想使用数组relative_positions
生成数组points
。 points
可以担任N
个职位(我一次最多可以拥有50-100个业务代表)。
因此,使用上述points
,我想产生输出:
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]]
例如,给定四个代理位置以numpy数组存储:
agent_points = np.array([[10, 1],
[30, 3],
[25, 10],
[5, 5]])
我想生成输出:
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个案例(因为这是从代理到其自身的相对位置),但是我认为这不是“纯粹的”方法,因为我可能会意外删除恰好恰好在同一点(或非常接近)的特工
答案 0 :(得分:1)
方法1
使用a
输入数组,您可以--p
d = (a-a[:,None,:])
valid_mask = ~np.eye(len(a),dtype=bool)
out = d[valid_mask]
基本上,我们将a
扩展到3D
,使第一个轴成为outer-broadcastable
,然后对其2D
版本进行减法运算,得到{{1} }整形的输出,其中mxmx2
是m
。示意性地放在-
a.shape[0]
创建a[:, None, :] : 4 x 1 x 2
a : 4 x 2
output : 4 x 4 x 2
的另一种方法是-
valid_mask
方法2
我们将利用r = np.arange(len(a))
valid_mask = r[:,None] != r
获得np.lib.stride_tricks.as_strided
数组(沿前两个轴)的非对角线遮罩,因此我们将在此处使用它来遮盖差异数组3D
。此掩码的生成受here
发布的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))
d = (a-a[:,None,:])
out = nodiag_view3D(d).reshape(-1,a.shape[1])
答案 1 :(得分:0)
虽然我没有numpy专用解决方案(我确定它存在),但是双重for循环和id检查可以解决问题。不过,points
的增长还需要一些时间。
points = [
[x1, y1],
[x2, y2],
[x3, y3]
]
relative_positions = []
for point1 in points:
for point2 in point:
if id(point1) != id(point2):
relative_positions.append([CALC_HERE_OR_FUNCTION])