我正在尝试编写一个函数,其参数是具有不同形状的数组。我有一些麻烦来理解列数组并使我的函数适用于所有形状的数组,这里是我发现的问题:
移调:
如果参数数组A
不是向量,那么我可以使用A.T
很好地转置它,但如果A
是行向量,则不会将A
转换为列向量。如果A
是列向量,则会(奇怪地)将其转换为行向量。有没有办法独立于其形状转置数组?
点积 带有标量的列向量的点乘积是列向量(是啊!)。具有1个元素numpy数组的列向量的点Product是行向量(nayyy)。
A = array((1,2)).reshape(2,1) #this is how I make a column vector (is there a better looking way?)
print dot(A,3) #column vector
b = dot(array((2,4)),a) #array with shape (1,)
print dot(A,b) #row vector..(bah)
反演
linalg.inv(array(2)) #gives an error, shouldn't it return 1/2 ?
感谢您的帮助! 附:对不起我是菜鸟我习惯了Matlab这种写东西的方式对我来说很混乱.. P.2.2我不想使用矩阵,因为数组更通用
答案 0 :(得分:9)
如果你已经习惯了Matlab,Numpy处理“列”和“行”向量的方式有点奇怪。要意识到的是,1-d数组既不是列也不是行向量。要成为列或行向量,数组必须是 2-d数组,其中一个维度设置为一个。您可以通过查看有多少个大括号来区分一维数组和一行二维数组:
>>> a = numpy.arange(15)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>> b = a.reshape(1, -1)
>>> b
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]])
现在您可以看到,当您转置这两个时,a
保持不变,但b
成为列向量:
>>> a.T
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>> b.T
array([[ 0],
[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[12],
[13],
[14]])
同样,这看起来有点奇怪 - 但正如你所说,“数组更为通用。”为了实现这种普遍性,Numpy严格区分不同维度的数组;在任何有意义的意义上,1-d数组都不能是“列”或“行”向量。第二个维度根本没有定义!
您的其他问题的答案来自此观察。你上面的代码示例代码为我生成了一个错误,所以我会做一些稍微不同的事情......这也会产生错误,但是信息量更大:
>>> A
array([[1],
[2]])
>>> B
array([2, 4])
>>> numpy.dot(A, B)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: objects are not aligned
Numpy抱怨对象没有对齐。那是因为B是1-d阵列!让它成为一个真正的行向量:
>>> B = B.reshape(1, -1)
>>> B
array([[2, 4]])
>>> numpy.dot(A, B)
array([[2, 4],
[4, 8]])
>>> numpy.dot(B, A)
array([[10]])
现在一切都有道理。 Dot只是在这里执行矩阵乘法;按一个顺序,该操作产生一个2x2阵列;另一方面,它产生一个1x1阵列。注意大括号的数量!这两个都是 2-d 数组。反过来,10
,[10]
和[[10]]
会有不同的结果。
同样,请考虑以下三个值:
>>> numpy.array(2)
array(2)
>>> numpy.array((2,))
array([2])
>>> numpy.array((2,)).reshape(1,-1)
array([[2]])
如果你将它们传递给numpy.linalg.inv
,你会得到除了最后一个之外的所有错误 - 你不能采用不是矩阵的矩阵逆矩阵!如果你传递最后一个,结果也是一个矩阵:
>>> numpy.linalg.inv(numpy.array((2,)).reshape(1,-1))
array([[ 0.5]])
答案 1 :(得分:1)
区分1D阵列和2D阵列很重要。您指的行向量是1D,而列向量是2D。为了证明这种差异,请看下面的例子。
首先,我们演示了转置2D数组的默认行为(即使列向量是一个简单的2D数组):
import numpy as np
print np.ones((3, 4)).T.shape
print np.ones((3, 1)).T.shape
输出是 - 正如所料:
(4, 3)
(1, 3)
然而,1D向量不会改变其大小:
print np.ones((3,)).T.shape
输出:
(3,)
要快速将其转换为2D数组,请使用[:,None]
:
print np.ones((3,))[:,None].T.shape
输出:
(1, 3)
要获得所需的结果,最好使用2D数组:
A = np.ones((2, 1) # column vector
b = np.ones((1, 1)) # scalar
print np.dot(A, b) # column vector (as expected)
输出:
[[ 1.]
[ 1.]]
呀! :)
同样,您需要确保使用2D数组。这可以使用ndmin
参数来完成:
print np.linalg.inv(np.array(2,ndmin=2))
输出:
[[ 0.5]]