numpy的转置方法无法将一维行ndarray转换为第一列

时间:2019-10-19 15:47:10

标签: python arrays numpy transpose numpy-ndarray

让我们考虑将a作为一维行/水平数组:

import numpy as np
N = 10
a = np.arange(N) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a.shape # (10,)

现在我想让b的一维列/垂直数组转置为a

b = a.transpose() # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b.shape # (10,)

但是.transpose()方法会返回一个完全相同形状的ndarray!

我希望看到的是

np.array([[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]])

可以通过

实现
c = a.reshape(a.shape[0], 1) # or c = a; c.shape = (c.shape[0], 1)
c.shape # (10, 1)

令我惊讶的是,它的形状为(10, 1)而不是(1, 10)

在Octave / Scilab中,我可以这样做:

N = 10
b = 0:(N-1)
a = b'
size(b) % ans = 1   10
size(a) % ans = 10   1

我了解numpy ndarray并不是矩阵(如here所述),但是numpy的转置函数的行为对我而言毫无意义!如果您能帮助我了解这种行为的合理性以及我在这里缺少的内容,我将不胜感激。

PS 因此,到目前为止,我了解的是b = a.transpose()相当于b = a; b.shape = b.shape[::-1],如果您拥有(N, 1)的“二维数组”,返回一个(1, N)形状的数组,就像您期望的转置运算符一样。但是,numpy似乎将(N,)的“ 1D数组”视为0D标量。我认为他们应该将这个方法命名为其他方法,因为这很容易引起误解/混淆。

2 个答案:

答案 0 :(得分:3)

要更好地理解numpy数组,您应该看一下这篇评论文章:The NumPy array: a structure for efficient numerical computation

简而言之,numpy ndarray具有称为跨步的属性,即

  

在内存中跳过以继续进行下一个元素的字节数。   例如,对于字节数组(10,10),步幅可以是(10,   1),换句话说:继续执行一个字节到达下一列,然后再十   个字节来定位下一行。

对于您的ndarray aa.stride = (8,),这表明它仅是一维的,要到达该单维的下一个元素,您需要前进内存中有8个字节(每个int为64位)。

步幅对于表示转置很有用:

  

通过修改步幅,例如,可以转置数组或   以零成本进行了整形(无需复制任何内存)。

因此,如果存在二维ndarray,例如说b = np.ones((3,5)),则b.strides = (40, 8),而b.transpose().strides = (8, 40)。因此,如您所见,转置的2D-ndarray就是完全相同的数组,其步幅已重新排序。而且由于您的一维ndarray只有一维,因此交换其步幅的值(即进行其转置)不会做任何事情。

答案 1 :(得分:1)

您已经提到numpy数组不是矩阵。转置功能的定义如下

  

排列数组的尺寸。

这意味着numpy的转置方法会将数据从一个维度移动到另一个维度。由于一维数组只有一个维度,因此没有其他维度可以移动数据t0。因此,您需要在转置生效之前添加尺寸。与高维数组(3D,4D ...)数组保持一致时,这种行为也是有意义的。

有一种干净的方法来实现您想要的东西

N = 10
a = np.arange(N)
a[ :, np.newaxis]