2D NumPy 数组的蛇形遍历
Snake traversal of 2D NumPy array
我有以下二维数组:
In [173]: arr
Out[173]:
array([[ 1, 2, 3, 4], # -> -> -> ->
[ 5, 6, 7, 8], # <- <- <- <-
[ 9, 10, 11, 12], # -> -> -> ->
[13, 14, 15, 16], # <- <- <- <-
[17, 18, 19, 20]]) # -> -> -> ->
我想遍历 中的数组,从左上角元素开始,到右下角元素结束。
截至目前,我有这种无趣的解决方法:
In [187]: np.hstack((arr[0], arr[1][::-1], arr[2], arr[3][::-1], arr[4]))
Out[187]:
array([ 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12, 16, 15, 14, 13, 17,
18, 19, 20])
我们如何才能以最小的努力做到这一点,而无需循环且无需过多的硬编码?
一种方法是从输入的副本开始,然后用输入中相应行的列翻转版本替换第二行,并使用步长切片对所有偶数行执行此操作。最后,对于所需的扁平化版本,末尾需要一个 ravel()
。
因此,实现看起来像这样 -
out = arr.copy()
out[1::2] = arr[1::2,::-1]
out = out.ravel()
另一种紧凑的方法是使用 np.where
在 col-flipped 和 non-flipped 版本之间进行选择,从而实现我们想要的输出 -
np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr).ravel()
给定样本的解释 -
# Array to be used for the chosing. 1s would be True ones and 0s are False
In [72]: np.arange(len(arr))[:,None]%2
Out[72]:
array([[0],
[1],
[0],
[1],
[0]])
# Use np.where to choose. So, arr[:,::-1] must be the first data, as
# that's one to be put on even rows and arr would be the second one.
In [73]: np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr)
Out[73]:
array([[ 1, 2, 3, 4],
[ 8, 7, 6, 5],
[ 9, 10, 11, 12],
[16, 15, 14, 13],
[17, 18, 19, 20]])
# Finally flatten
In [74]: np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr).ravel()
Out[74]:
array([ 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12, 16, 15, 14, 13, 17,
18, 19, 20])
我有以下二维数组:
In [173]: arr
Out[173]:
array([[ 1, 2, 3, 4], # -> -> -> ->
[ 5, 6, 7, 8], # <- <- <- <-
[ 9, 10, 11, 12], # -> -> -> ->
[13, 14, 15, 16], # <- <- <- <-
[17, 18, 19, 20]]) # -> -> -> ->
我想遍历
截至目前,我有这种无趣的解决方法:
In [187]: np.hstack((arr[0], arr[1][::-1], arr[2], arr[3][::-1], arr[4]))
Out[187]:
array([ 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12, 16, 15, 14, 13, 17,
18, 19, 20])
我们如何才能以最小的努力做到这一点,而无需循环且无需过多的硬编码?
一种方法是从输入的副本开始,然后用输入中相应行的列翻转版本替换第二行,并使用步长切片对所有偶数行执行此操作。最后,对于所需的扁平化版本,末尾需要一个 ravel()
。
因此,实现看起来像这样 -
out = arr.copy()
out[1::2] = arr[1::2,::-1]
out = out.ravel()
另一种紧凑的方法是使用 np.where
在 col-flipped 和 non-flipped 版本之间进行选择,从而实现我们想要的输出 -
np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr).ravel()
给定样本的解释 -
# Array to be used for the chosing. 1s would be True ones and 0s are False
In [72]: np.arange(len(arr))[:,None]%2
Out[72]:
array([[0],
[1],
[0],
[1],
[0]])
# Use np.where to choose. So, arr[:,::-1] must be the first data, as
# that's one to be put on even rows and arr would be the second one.
In [73]: np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr)
Out[73]:
array([[ 1, 2, 3, 4],
[ 8, 7, 6, 5],
[ 9, 10, 11, 12],
[16, 15, 14, 13],
[17, 18, 19, 20]])
# Finally flatten
In [74]: np.where(np.arange(len(arr))[:,None]%2,arr[:,::-1],arr).ravel()
Out[74]:
array([ 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12, 16, 15, 14, 13, 17,
18, 19, 20])