我想制作一个(x,y)点的轨迹,这些点在偶数网格中曲折。我希望能够指定开始的轴。是否有一种有效的方法可以用numpy做到这一点?
例如:
xv, yv = np.meshgrid([1,2,3], [4,5])
产生
xv: [[1 2 3]
[1 2 3]]
yv: [[4 4 4]
[5 5 5]]
我希望我的轨迹是:
(1,4), (2,4), (3,4), (3,5), (2,5), (1,5)
或
(1,4), (1,5), (2,5), (2,4), (3,4), (3,5)
答案 0 :(得分:4)
您可以使用以下方法每隔一行翻转坐标:
xv[1::2] = xv[1::2,::-1]
然后堆叠xv
和yv
。
xv, yv = np.meshgrid([1,2,3], [4,5])
xv[1::2] = xv[1::2,::-1]
xv
#array([[1, 2, 3],
# [3, 2, 1]])
np.stack((xv, yv), axis=-1).reshape(-1, 2)
#array([[1, 4],
# [2, 4],
# [3, 4],
# [3, 5],
# [2, 5],
# [1, 5]])
或翻转yv
:
xv, yv = np.meshgrid([1,2,3], [4,5])
yv[:,1::2] = yv[::-1, 1::2]
yv
#array([[4, 5, 4],
# [5, 4, 5]])
np.stack((xv.T, yv.T), axis=-1).reshape(-1, 2)
#array([[1, 4],
# [1, 5],
# [2, 5],
# [2, 4],
# [3, 4],
# [3, 5]])
答案 1 :(得分:3)
我们可以通过直接处理1D
数组作为两个输出数组的array-initialization
的性能度量来避免创建繁重的meshgrids,然后通过广播的赋值来分配输入数组一次偶数编号的地方,沿着奇数编号的地方翻转。这为我们提供了曲折排序。
实施将是 -
def create_zigzag_grids(a,b):
m,n = len(b), len(a)
out1 = np.empty((m,n,2),dtype=int)
out1[:,:,1] = b[:,None]
out1[::2,:,0] = a
out1[1::2,:,0] = a[::-1]
out2 = np.empty((n,m,2),dtype=int)
out2[:,:,0] = a[:,None]
out2[::2,:,1] = b
out2[1::2,:,1] = b[::-1]
return out1.reshape(-1,2), out2.reshape(-1,2)
示例运行 -
1)输入和输出:
In [748]: a,b = np.array([1,2,3,4]), np.array([5,6,7])
...: out1, out2 = create_zigzag_grids(a,b)
...:
2)创建meshgrid以验证我们的结果:
In [749]: xv, yv = np.meshgrid(a,b)
In [750]: xv
Out[750]:
array([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
In [751]: yv
Out[751]:
array([[5, 5, 5, 5],
[6, 6, 6, 6],
[7, 7, 7, 7]])
3)验证结果:
In [752]: out1
Out[752]:
array([[1, 5],
[2, 5],
[3, 5],
[4, 5],
[4, 6],
[3, 6],
[2, 6],
[1, 6],
[1, 7],
[2, 7],
[3, 7],
[4, 7]])
In [753]: out2
Out[753]:
array([[1, 5],
[1, 6],
[1, 7],
[2, 7],
[2, 6],
[2, 5],
[3, 5],
[3, 6],
[3, 7],
[4, 7],
[4, 6],
[4, 5]])
运行时测试
其他方法 -
def Psidom(a,b): # @Psidom's stack based soln
xv, yv = np.meshgrid(a,b)
xv[1::2] = xv[1::2,::-1]
out1 = np.stack((xv, yv), axis=-1).reshape(-1, 2)
yv[:,1::2] = yv[::-1, 1::2]
out2 = np.stack((xv.T, yv.T), axis=-1).reshape(-1, 2)
return out1, out2
计时 -
In [829]: a = np.arange(100)
...: b = np.arange(100)+100
In [830]: %timeit Psidom(a,b)
...: %timeit create_zigzag_grids(a,b)
10000 loops, best of 3: 133 µs per loop
10000 loops, best of 3: 25.1 µs per loop
In [831]: a = np.arange(1000)
...: b = np.arange(1000)+1000
In [832]: %timeit Psidom(a,b)
...: %timeit create_zigzag_grids(a,b)
10 loops, best of 3: 23.8 ms per loop
100 loops, best of 3: 5.2 ms per loop