在一个数组中转置数组

5

我有一个形状为(M*N,N)的二维数组,实际上由MN*N数组组成。我想以向量化的方式转置所有这些元素(N*N矩阵)。例如,

import numpy as np
A=np.arange(1,28).reshape((9,3))
print "A before transposing:\n", A
for i in range(3):
    A[i*3:(i+1)*3,:]=A[i*3:(i+1)*3,:].T
print "A after transposing:\n", A

这段代码会生成以下输出:
A before transposing: 
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]
 [13 14 15]
 [16 17 18]
 [19 20 21]
 [22 23 24]
 [25 26 27]]
A after transposing: 
 [[ 1  4  7]
 [ 2  5  8]
 [ 3  6  9]
 [10 13 16]
 [11 14 17]
 [12 15 18]
 [19 22 25]
 [20 23 26]
 [21 24 27]]

我知道。但我想要矢量化版本。

你所说的“向量化”,是指一个由三个3x3列表组成的列表吗? - Sufian Latif
1
@605002,通过向量化,我的意思是不使用for循环(而是使用numpy方法来操作numpy数组)。 - Cupitor
2个回答

8

以下是一个麻烦但可行的一行代码实现方法!

A.reshape((-1, 3, 3)).swapaxes(-1, 1).reshape(A.shape)

一步一步地操作,将其重塑为(3, 3, 3)

>>> A.reshape((-1, 3, 3))
array([[[ 1,  2,  3],
        [ 4,  5,  6],
        [ 7,  8,  9]],

       [[10, 11, 12],
        [13, 14, 15],
        [16, 17, 18]],

       [[19, 20, 21],
        [22, 23, 24],
        [25, 26, 27]]])

然后在每个子数组上执行类似于转置的操作swapaxes

>>> A.reshape((-1, 3, 3)).swapaxes(-1, 1)
array([[[ 1,  4,  7],
        [ 2,  5,  8],
        [ 3,  6,  9]],

       [[10, 13, 16],
        [11, 14, 17],
        [12, 15, 18]],

       [[19, 22, 25],
        [20, 23, 26],
        [21, 24, 27]]])

最后将其重塑为(9, 3)
>>> A.reshape((-1, 3, 3)).swapaxes(-1, 1).reshape(A.shape)
array([[ 1,  4,  7],
       [ 2,  5,  8],
       [ 3,  6,  9],
       [10, 13, 16],
       [11, 14, 17],
       [12, 15, 18],
       [19, 22, 25],
       [20, 23, 26],
       [21, 24, 27]])
>>> 

我认为无论使用何种方法,都必须复制数据,因为没有二维步幅/形状可以生成以下结果:

array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
       18, 19, 20, 21, 22, 23, 24, 25, 26, 27])

(有吗?) 在我的版本中,我认为数据是在最后的重塑步骤中复制的。


请问您能否对正在发生的事情进行评论?谢谢。 - Cupitor

3
In [42]: x = np.arange(1,28).reshape((9,3))

In [43]: x
Out[43]: 
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15],
       [16, 17, 18],
       [19, 20, 21],
       [22, 23, 24],
       [25, 26, 27]])


In [31]: r,c = x.shape
In [39]: z = np.vstack(np.hsplit(x.T,r/c))

In [45]: z
Out[45]: 
array([[ 1,  4,  7],
       [ 2,  5,  8],
       [ 3,  6,  9],
       [10, 13, 16],
       [11, 14, 17],
       [12, 15, 18],
       [19, 22, 25],
       [20, 23, 26],
       [21, 24, 27]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接