Python 使用重复行将二维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。 我尝试的代码是:

我有一个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。 我尝试的代码是:

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]]])