1

好的,我知道如何转置矩阵,例如:

A = np.arange(25).reshape(5, 5)
print A
array([[ 0,  1,  2,  3,  4],
   [ 5,  6,  7,  8,  9],
   [10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19],
   [20, 21, 22, 23, 24]])
A.T
array([[ 0,  5, 10, 15, 20],
   [ 1,  6, 11, 16, 21],
   [ 2,  7, 12, 17, 22],
   [ 3,  8, 13, 18, 23],
   [ 4,  9, 14, 19, 24]])

对于一维数组,不可能使用这个“.T”工具(老实说,我不知道为什么)所以要转置一个向量,你必须改变范式并使用,例如:

B = np.arange(5) 
print B
array([0, 1, 2, 3, 4])

并且因为B.T会给出相同的结果,所以我们应用这种范式变化,使用:

B[ :, np.newaxis]
array([[0],
   [1],
   [2],
   [3],
   [4]])

而且我发现这种范式变化有点反感,因为一维向量与二维向量(矩阵)绝不是不同的实体,从数学上讲它们来自同一个家庭并共享许多事物。

我的问题是:是否有可能用 numpy 皇冠上的宝石(有时称为)einsum 进行这种换位,以更紧凑和统一的方式用于每种张量?我知道你做的矩阵

np.einsum('ij->ji', A)

你会得到,就像以前一样A.T

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

是否可以使用一维数组来做到这一点?

先感谢您。

4

2 回答 2

4

是的,您可以使用转置一维数组einsum

In [17]: B = np.arange(5)
In [35]: np.einsum('i,j->ji', np.ones(1), B)
Out[35]: 
array([[ 0.],
       [ 1.],
       [ 2.],
       [ 3.],
       [ 4.]])

但这并不是真正einsum的用途,因为einsum它是计算产品的总和。正如您所料,它比简单地添加新轴要慢。

In [36]: %timeit np.einsum('i,j->ji', np.ones(1), B)
100000 loops, best of 3: 5.43 µs per loop

In [37]: %timeit B[:, None]
1000000 loops, best of 3: 230 ns per loop

如果您正在寻找用于转置 1D 或 2D 数组的单一语法,这里有两个选项:

  • 使用np.atleast_2d(b).T

    In [39]: np.atleast_2d(b).T
    Out[39]: 
    array([[0],
           [1],
           [2],
           [3],
           [4]])
    
    In [40]: A = np.arange(25).reshape(5,5)
    
    In [41]: np.atleast_2d(A).T
    Out[41]: 
    array([[ 0,  5, 10, 15, 20],
           [ 1,  6, 11, 16, 21],
           [ 2,  7, 12, 17, 22],
           [ 3,  8, 13, 18, 23],
           [ 4,  9, 14, 19, 24]])
    
  • 使用np.matrix

    In [44]: np.matrix(B).T
    Out[44]: 
    matrix([[0],
            [1],
            [2],
            [3],
            [4]])
    
    In [45]: np.matrix(A).T
    Out[45]: 
    matrix([[ 0,  5, 10, 15, 20],
            [ 1,  6, 11, 16, 21],
            [ 2,  7, 12, 17, 22],
            [ 3,  8, 13, 18, 23],
            [ 4,  9, 14, 19, 24]])
    

    Amatrix是 的子类ndarray。它是一个专门的类,为处理矩阵和向量提供了很好的语法。所有矩阵对象(矩阵和向量)都是二维的——向量被实现为具有单列或单行的二维矩阵:

    In [47]: np.matrix(B).shape     # one row
    Out[47]: (1, 5)
    
    In [48]: np.matrix(B).T.shape   # one column
    Out[48]: (5, 1)
    

    matrixs 和ndarrayss之间还有其他区别。该* 运算符计算matrixs 的矩阵乘法,但对 执行逐元素乘法ndarrays。如果 您使用np.matrix.


顺便说一句,NumPy 定义转置的方式有一定的美感ndarrays。请记住,ndinndarray暗示了这些对象可以表示N一维数组的事实。因此,无论这些对象使用什么定义,都.T必须适用于N维度。

特别是,.T 反转轴的顺序

在二维中,反转轴的顺序与矩阵转置一致。在一维中,转置什么都不做——反转单个轴的顺序会返回相同的轴。美妙的部分是这个定义适用于 N 维。

于 2016-04-25T12:58:22.837 回答
0

的基本动作einsum是迭代所有维度来执行一些乘积之和。在少数情况下,它会走捷径,如果可以的话,甚至会返回视图。

但我认为它会抱怨'i->j'或'i->ij'。您不能在右侧拥有左侧尚未存在的索引。

einsum('i,j->ji',A,[1])或一些变体,可能会起作用。但它会慢很多。

In [19]: np.einsum('i,j->ij',[1,2,3],[1])
Out[19]: 
array([[1],
       [2],
       [3]])

In [30]: %%timeit x=np.arange(1000)
    ...: y=x[:,None]
1000000 loops, best of 3: 439 ns per loop

In [31]: %%timeit x=np.arange(1000)
    ...: np.einsum('i,j->ij',x,[1])
100000 loops, best of 3: 15.3 µs per loop
于 2016-04-25T12:55:30.883 回答