numpy列数组和奇怪的结果

时间:2014-10-04 17:38:32

标签: python arrays numpy

我正在尝试编写一个函数,其参数是具有不同形状的数组。我有一些麻烦来理解列数组并使我的函数适用于所有形状的数组,这里是我发现的问题:

移调: 如果参数数组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我不想使用矩阵,因为数组更通用

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]]