将2D阵列复制到3D中,减去一行n次

时间:2017-04-29 21:55:34

标签: python arrays python-2.7 python-3.x numpy

我有一个2D数组,我需要将它变成一个3D数组 - 下一层从第一层的第二行开始。

这是我最好的尝试,用四个层来直观地展示我想要做的事情':

# original array
dat = np.array([[0, 0, 0, 0, 9]
                [1, 1, 1, 1, 9],
                [2, 2, 2, 2, 9],
                [3, 3, 3, 3, 9],
                [4, 4, 4, 4, 9],
                [5, 5, 5, 5, 9],
                [6, 6, 6, 6, 9],
                [7, 7, 7, 7, 9],
                [8, 8, 8, 8, 9]], np.int32
              )

#dat.shape
#(8, 5)

layers = 4

# new 3d array

# first 'layer'
[0, 0, 0, 0, 9],
[1, 1, 1, 1, 9],
[2, 2, 2, 2, 9],
[3, 3, 3, 3, 9],
[4, 4, 4, 4, 9],
[5, 5, 5, 5, 9]

# second 'layer'
[1, 1, 1, 1, 9],
[2, 2, 2, 2, 9],
[3, 3, 3, 3, 9],
[4, 4, 4, 4, 9],
[5, 5, 5, 5, 9],
[6, 6, 6, 6, 9]

# third 'layer'
[2, 2, 2, 2, 9],
[3, 3, 3, 3, 9],
[4, 4, 4, 4, 9],
[5, 5, 5, 5, 9],
[6, 6, 6, 6, 9],
[7, 7, 7, 7, 9]

# fourth 'layer'
[3, 3, 3, 3, 9],
[4, 4, 4, 4, 9],
[5, 5, 5, 5, 9],
[6, 6, 6, 6, 9],
[7, 7, 7, 7, 9],
[8, 8, 8, 8, 9]

# new shape: (rows, layers, columns)
#dat.shape
#(6, 4, 5)

我意识到我对图层的视觉表现可能不是我说它最终的方式,但这就是我试图将其加入的形状。

我尝试过的解决方案包含np.repeat(dat[:, :, np.newaxis], steps, axis=2)的变体,但出于某种原因,一旦超过两个维度,我就会挣扎。

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

方法#1:这是使用broadcasting的一种方法 -

layers = 4
L = dat.shape[0]-layers+1
out = dat[np.arange(L) + np.arange(layers)[:,None]]

如果您确实需要(6,4,5)形状的数组,我们需要稍作修改:

out = dat[np.arange(L)[:,None] + np.arange(layers)]

方法#2:这是另一个NumPy strides -

strided = np.lib.stride_tricks.as_strided
m,n = dat.strides
N = dat.shape[1]
out = strided(dat, shape = (layers,L,N), strides= (m,N*n,n))

对于(6,4,5)形状的输出数组,

out = strided(dat, shape = (L,layers,N), strides= (N*n,m,n))

请注意,第二种方法会创建输入数组dat的视图,并且创建效率非常高。如果您需要副本,请在结尾添加.copy()out.copy()

(6,4,5)输出的示例输出 -

In [267]: out[:,0,:]
Out[267]: 
array([[0, 0, 0, 0, 9],
       [1, 1, 1, 1, 9],
       [2, 2, 2, 2, 9],
       [3, 3, 3, 3, 9],
       [4, 4, 4, 4, 9],
       [5, 5, 5, 5, 9]])

In [268]: out[:,1,:]
Out[268]: 
array([[1, 1, 1, 1, 9],
       [2, 2, 2, 2, 9],
       [3, 3, 3, 3, 9],
       [4, 4, 4, 4, 9],
       [5, 5, 5, 5, 9],
       [6, 6, 6, 6, 9]])

In [269]: out[:,2,:]
Out[269]: 
array([[2, 2, 2, 2, 9],
       [3, 3, 3, 3, 9],
       [4, 4, 4, 4, 9],
       [5, 5, 5, 5, 9],
       [6, 6, 6, 6, 9],
       [7, 7, 7, 7, 9]])

In [270]: out[:,3,:]
Out[270]: 
array([[3, 3, 3, 3, 9],
       [4, 4, 4, 4, 9],
       [5, 5, 5, 5, 9],
       [6, 6, 6, 6, 9],
       [7, 7, 7, 7, 9],
       [8, 8, 8, 8, 9]])