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 ndarrays 不是矩阵(如此处所讨论的),但是 numpy 的转置函数的行为对我来说没有意义!如果您能帮助我了解这种行为的意义以及我在这里缺少什么,我将不胜感激。


PS所以到目前为止我所理解b = a.transpose()的是b = a; b.shape = b.shape[::-1],如果你有一个“二维数组”,(N, 1)它将返回一个(1, N)整形数组,正如你对转置运算符所期望的那样。但是,numpy 似乎将“一维数组”(N,)视为 0D 标量。我认为他们应该将此方法命名为其他名称,因为这非常具有误导性/令人困惑的恕我直言。


一只名叫tom的猫
浏览 235回答 2
2回答

泛舟湖上清波郎朗

简而言之,numpy ndarrays 有这个属性叫做 stride,也就是要在内存中跳过以继续到下一个元素的字节数。例如,对于 (10, 10) 字节数组,步长可能是 (10, 1),换句话说:前进一个字节以到达下一列,前进 10 个字节以定位下一行。对于您的 ndarray a,a.stride= (8,),这表明它只是一维的,并且要到达该一维上的下一个元素,您需要在内存中提前 8 个字节(每个 int 是 64 位)。步幅对于表示转置很有用:例如,通过修改步幅,可以零成本转置或重塑数组(无需复制内存)。因此,如果有一个二维 ndarray,b = np.ones((3,5))例如,然后b.strides= (40, 8),而b.transpose().strides= (8, 40)。因此,如您所见,转置的 2D-ndarray 只是完全相同的数组,其步幅已重新排序。而且由于您的一维 ndarray 只有一维,因此交换其步幅的值(即取其转置)不会做任何事情。

慕盖茨4494581

正如您已经提到的,numpy 数组不是矩阵。转置函数的定义如下置换数组的维度。这意味着 numpy 的转置方法会将数据从一个维度移动到另一个维度。由于一维数组只有一个维度,因此没有其他维度可以移动数据 t0。所以你需要在转置有任何效果之前添加一个维度。这种行为对于与更高维数组(3D、4D ...)数组保持一致也是有意义的。有一种干净的方法可以实现您想要的N = 10a = np.arange(N)a[ :, np.newaxis]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python