在切片上转置 Numpy 数组

Transposing a Numpy Array on a slice

我有一个 2d 数组,我正在尝试创建一个 3d 数组,其中每一行都是原始数组的重复元素,在本例中为 9 次。我认为这涉及转置某种 np 切片....我的 numpy 技能有点粗糙...

这是一个例子:

输入:

an_array = np.array([1,2,3,4,5,6])
a = an_array.reshape(3,2)
a

array([[1, 2],
       [3, 4],
       [5, 6]])

我想要的输出如下:

array([[[1, 1, 1, 1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2, 2, 2, 2]],

        [[3, 3, 3, 3, 3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4, 4, 4, 4, 4]],

        [[5, 5, 5, 5, 5, 5, 5, 5, 5],
        [6, 6, 6, 6, 6, 6, 6, 6, 6]]])

这是我的想法,但它并没有完全给出所需的输出。行的顺序错误加上形状是 (2,3,9) 而不是 (3,2,9),这是一个很容易解决的问题,但无论如何,我想知道是否有快速的方法这个?

new = np.transpose([a[:]]*9)
new

array([[[1, 1, 1, 1, 1, 1, 1, 1, 1],
        [3, 3, 3, 3, 3, 3, 3, 3, 3],
        [5, 5, 5, 5, 5, 5, 5, 5, 5]],

       [[2, 2, 2, 2, 2, 2, 2, 2, 2],
        [4, 4, 4, 4, 4, 4, 4, 4, 4],
        [6, 6, 6, 6, 6, 6, 6, 6, 6]]])

尝试转置 vstack,然后重塑

a = np.transpose([np.vstack(an_array)]*9)
a.reshape(3,2,9)
In [102]: arr = np.arange(1,7).reshape(3,2)
In [103]: arr
Out[103]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

你没有显示中间步骤,但我认为它是:

In [104]: arr.repeat(4)
Out[104]: 
array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
       6, 6])
In [105]: arr.repeat(4).reshape(3,2,4)
Out[105]: 
array([[[1, 1, 1, 1],
        [2, 2, 2, 2]],

       [[3, 3, 3, 3],
        [4, 4, 4, 4]],

       [[5, 5, 5, 5],
        [6, 6, 6, 6]]])

它的转置很容易,而且相对便宜(在 numpy 中)

In [106]: arr.repeat(4).reshape(3,2,4).transpose(1,0,2)
Out[106]: 
array([[[1, 1, 1, 1],
        [3, 3, 3, 3],
        [5, 5, 5, 5]],

       [[2, 2, 2, 2],
        [4, 4, 4, 4],
        [6, 6, 6, 6]]])

repeat 允许您指定轴。你想在一个新的最后一个轴上扩展,但你也想要一个 (2,3) 而不是 `(3,2),所以从 transpose

开始
In [4]: arr.T[:,:,None]
Out[4]: 
array([[[1],
        [3],
        [5]],

       [[2],
        [4],
        [6]]])
In [5]: arr.T[:,:,None].repeat(4,axis=2)
Out[5]: 
array([[[1, 1, 1, 1],
        [3, 3, 3, 3],
        [5, 5, 5, 5]],

       [[2, 2, 2, 2],
        [4, 4, 4, 4],
        [6, 6, 6, 6]]])

或直接用于 (3,2,n):

In [9]: arr[:,:,None].repeat(4,axis=2)
Out[9]: 
array([[[1, 1, 1, 1],
        [2, 2, 2, 2]],

       [[3, 3, 3, 3],
        [4, 4, 4, 4]],

       [[5, 5, 5, 5],
        [6, 6, 6, 6]]])

所有这些操作都相对便宜,因此可以根据需要混合搭配。

该死的 browliv 回答得很好

reshape 并使用广播

a_out = a.reshape(3,-1,1) * np.ones(9)

Out[40]:
array([[[1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [2., 2., 2., 2., 2., 2., 2., 2., 2.]],

       [[3., 3., 3., 3., 3., 3., 3., 3., 3.],
        [4., 4., 4., 4., 4., 4., 4., 4., 4.]],

       [[5., 5., 5., 5., 5., 5., 5., 5., 5.],
        [6., 6., 6., 6., 6., 6., 6., 6., 6.]]])

或者

a_out = np.broadcast_to(np.reshape(a, (3,-1,1)), (3,2,9))

Out[43]:
array([[[1, 1, 1, 1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2, 2, 2, 2]],

       [[3, 3, 3, 3, 3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4, 4, 4, 4, 4]],

       [[5, 5, 5, 5, 5, 5, 5, 5, 5],
        [6, 6, 6, 6, 6, 6, 6, 6, 6]]])