Python新手来自MATLAB背景。
我有一个1列数组,我想将该列移动到3列数组的第一列。有了MATLAB背景,我就会这样做:
import numpy as np
A = np.zeros([150,3]) #three column array
B = np.ones([150,1]) #one column array which needs to replace the first column of A
#MATLAB-style solution:
A[:,0] = B
然而这不起作用,因为A的“形状”是(150,3)而B的“形状”是(150,1)。并且显然命令A [:,0]导致(150)的“形状”。
现在,(150,1)和(150)之间有什么区别?它们不是同一个东西:列向量?为什么Python不够“足够聪明”才能弄清楚我想将列向量B放入A的第一列?
有没有一种简单的方法可以将形状为(N,1)的1列向量转换为形状为(N)的1列向量?
我是Python新手,这似乎是一个非常愚蠢的事情,MATLAB做得更好......
答案 0 :(得分:3)
有几件事是不同的。在numpy
数组中可以是0d或1d或更高。在MATLAB中,2d是最小的(并且一度是唯一的维度)。 MATLAB很容易扩展尺寸,因为它是Fortran ordered
。 numpy
,默认为c ordered
,最容易扩展前面的维度。
In [1]: A = np.zeros([5,3])
In [2]: A[:,0].shape
Out[2]: (5,)
简单索引会缩小维度,无论其是A[0,:]
还是A[:,0]
。与3D MATLAB矩阵相反,A(1,:,:)
v A(:,:,1)
。
numpy
执行broadcasting
,在总和和分配等操作期间调整维度。一个基本规则是,如果需要,维度可以自动扩展到开头:
In [3]: A[:,0] = np.ones(5)
In [4]: A[:,0] = np.ones([1,5])
In [5]: A[:,0] = np.ones([5,1])
...
ValueError: could not broadcast input array from shape (5,1) into shape (5)
它可以将(5,)
LHS更改为(1,5),但不能将其更改为(5,1)。
另一个广播示例+
:
In [6]: A[:,0] + np.ones(5);
In [7]: A[:,0] + np.ones([1,5]);
In [8]: A[:,0] + np.ones([5,1]);
现在(5,)与(5,1)一起使用,但那是因为它变为(1,5),它与(5,1)一起产生(5,5) - 外部产品广播:
In [9]: (A[:,0] + np.ones([5,1])).shape
Out[9]: (5, 5)
在Octave
>> x = ones(2,3,4);
>> size(x(1,:,:))
ans =
1 3 4
>> size(x(:,:,1))
ans =
2 3
>> size(x(:,1,1) )
ans =
2 1
>> size(x(1,1,:) )
ans =
1 1 4
要进行您想要调整任务的作业
索引以保留维度数的方式:
In [11]: A[:,[0]].shape
Out[11]: (5, 1)
In [12]: A[:,[0]] = np.ones([5,1])
将(5,1)转置为(1,5):
In [13]: A[:,0] = np.ones([5,1]).T
将(5,1)变平/拉平为(5,):
In [14]: A[:,0] = np.ones([5,1]).flat
In [15]: A[:,0] = np.ones([5,1])[:,0]
squeeze
,ravel
也可以。
Octave中的一些快速测试表明,在尺寸不匹配方面,它更宽容。但numpy
优先考虑一致性。一旦理解了广播规则,行为就有意义了。
答案 1 :(得分:2)
使用squeeze方法消除尺寸为1的尺寸。
A[:,0] = B.squeeze()
或者只是创建一维的B开头:
B = np.ones([150])
NumPy维持1D数组和维度为1的2D数组之间的区别这一事实是合理的,尤其是当人们开始使用n维数组时。
回答标题中的问题:形状(3,)
之间存在明显的结构差异,例如
[1, 2, 3]
和形状(3, 1)
的数组,例如
[[1], [2], [3]]