我想知道在numpy中为什么会存在维度为(length, 1)的一维数组和维度为(length,)的一维数组两种情况。
我经常遇到这种情况,例如在使用np.concatenate()时,需要先进行reshape步骤,或者我可以直接使用hstack/vstack。
我无法想象为什么这种行为是有必要的。有人能解释一下吗?
编辑:
其中一个评论建议我的问题可能是重复的。我更关注Numpy的基本工作逻辑,而不是区分一维和二维数组之间的区别,这是我认为被提到的线程的重点。
ndarray
的数据存储为一维缓冲区 - 只是一块内存。数组的多维特性由shape
和strides
属性及使用它们的代码产生。
numpy
的开发者选择允许任意数量的维度,因此形状和步幅表示为任意长度的元组,包括0和1。numpy
的np.matrix
仍然遵循旧的2d MATLAB约束。x [1] [2]
样式的索引。In [48]: x=np.arange(10)
In [49]: x.shape
Out[49]: (10,)
In [50]: x.strides
Out[50]: (4,)
In [51]: x1=x.reshape(10,1)
In [52]: x1.shape
Out[52]: (10, 1)
In [53]: x1.strides
Out[53]: (4, 4)
In [54]: x2=np.concatenate((x1,x1),axis=1)
In [55]: x2.shape
Out[55]: (10, 2)
In [56]: x2.strides
Out[56]: (8, 4)
MATLAB 在末尾添加新的维度。它像 order='F'
数组一样排序其值,可以很容易地将 (n,1) 矩阵转换为 (n,1,1,1)。默认情况下,numpy
的排序方式为 order='C'
,并且可以轻松地在开头扩展数组维度。利用广播时理解这一点至关重要。
因此,x1 + x
是一个 (10,1)+(10,) => (10,1)+(1,10) => (10,10)。
由于广播,(n,)
数组更像是一个行向量而不是列向量,与 (n,1)
不同。
In [64]: np.matrix(x)
Out[64]: matrix([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
In [65]: _.shape
Out[65]: (1, 10)
concatenate
要求匹配维度,不使用广播调整维度。有一堆stack
函数可以缓解这个限制,但它们会在使用concatenate
之前调整维度。查看它们的代码(可读性很好的Python)。shape
元组,包括空的()
(0d数组),(n,)
1d和更高维度的数组。对于更高级的东西,了解步幅也很有帮助(例如查看转置的步幅和形状)。(x,1)
数组?是否存在特定情况下(x,)
数组具有优势? - Dahlai(x,1)
会显示为一列。一个 (1,x)
会显示为一行,但是多了一组 []
。我经常生成一维数组,例如 np.arange(10)
。我可能会将其重塑为 (5,2)
。只有在需要广播时才会添加尾随的 ,[:,None]
。 - hpaulj(x,)
是一个向量,而 (x,1)
则是一个矩阵吗? - weima(x)
根本不是元组(只是多余的)。然而,(x,)
是一个元组。>>> np.array([1, 2, 3]).shape
(3,)
>>> np.array([[1, 2, 3]]).shape
(1, 3)
重新塑形不会复制除非需要,所以使用起来是安全的。
(x,)
指的是向量,而不是矩阵。 - kennytm(x,1)
呢? - Dahlai