Python 使用重复行将二维NumPy阵列重塑为三维
我有一个NumPy数组,如下所示:Python 使用重复行将二维NumPy阵列重塑为三维,python,arrays,numpy,reshape,Python,Arrays,Numpy,Reshape,我有一个NumPy数组,如下所示: arr = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]) 我希望安排如下: [[[6,7,8,9,10], [1,2,3,4,5]], [[11,12,13,14,15], [6,7,8,9,10]], [[16,17,18,19,20], [11,12,13,14,15]]] 因此,基本上是一个3D阵列,阵列的每一行有2x5。 我尝试的代码是:
arr = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]])
我希望安排如下:
[[[6,7,8,9,10],
[1,2,3,4,5]],
[[11,12,13,14,15],
[6,7,8,9,10]],
[[16,17,18,19,20],
[11,12,13,14,15]]]
因此,基本上是一个3D阵列,阵列的每一行有2x5。
我尝试的代码是:
x=np.zeros([3,2,5])
for i in range(len(arr)):
x[i]=arr[i:i+2,:][::-1]
但这将导致以下输出:
[[[ 6. 7. 8. 9. 10.]
[ 1. 2. 3. 4. 5.]]
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]]
[[[ 6. 7. 8. 9. 10.]
[ 1. 2. 3. 4. 5.]]
[[11. 12. 13. 14. 15.]
[ 6. 7. 8. 9. 10.]]
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]]
[[[ 6. 7. 8. 9. 10.]
[ 1. 2. 3. 4. 5.]]
[[11. 12. 13. 14. 15.]
[ 6. 7. 8. 9. 10.]]
[[16. 17. 18. 19. 20.]
[11. 12. 13. 14. 15.]]]
不需要使用任何循环。切片就足够了:
x = np.zeros([3,2,5], dtype=int)
x[:,0] = arr[-3:,:]
x[:,1] = arr[:3,:]
基本上,您可以将所有页面中的第0行分配给arr
的最后3行,将所有页面中的第1行分配给arr的前3行。您可以使用一些将数组构造为输入数组上的多维滑动窗口:
import numpy as np
arr = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]])
# compute the strides and shape of the output array
in_strides = arr.strides
out_strides = in_strides[:1] + in_strides
out_shape = (3, 2) + arr.shape[-1:] # keep the last dimension's size
strided = np.lib.stride_tricks.as_strided(arr, strides=out_strides, shape=out_shape)
out_arr = strided[:, ::-1, :].copy() # use a copy to stay safe
只要out\u shape[-1]我们可以利用基于的方法来获得滑动窗口,上述方法就可以安全地工作
这只是输入数组的一个视图。因此,没有额外的内存开销,并且运行时几乎是空闲的。如果希望输出具有自己的内存空间,请在那里附加.copy()
,即x.copy()
样本运行-
In [15]: from skimage.util.shape import view_as_windows
In [16]: view_as_windows(arr,(2,arr.shape[1]))[:,0,::-1]
Out[16]:
array([[[ 6, 7, 8, 9, 10],
[ 1, 2, 3, 4, 5]],
[[11, 12, 13, 14, 15],
[ 6, 7, 8, 9, 10]],
[[16, 17, 18, 19, 20],
[11, 12, 13, 14, 15]]])
当我尝试执行您的代码尝试时,我得到了一个错误,正如我预期的那样。如果我将循环的范围
更改为范围(x.shape[0])
(即范围(len(x))
),我将得到您想要的结果。您确定粘贴的数组来自上述输入和代码吗?
from skimage.util.shape import view_as_windows
x = view_as_windows(arr,(2,arr.shape[1]))[:,0,::-1]
In [15]: from skimage.util.shape import view_as_windows
In [16]: view_as_windows(arr,(2,arr.shape[1]))[:,0,::-1]
Out[16]:
array([[[ 6, 7, 8, 9, 10],
[ 1, 2, 3, 4, 5]],
[[11, 12, 13, 14, 15],
[ 6, 7, 8, 9, 10]],
[[16, 17, 18, 19, 20],
[11, 12, 13, 14, 15]]])