2017-06-15 165 views
2

我是新来的numpy, 所以,有numpy,有可能使用矩阵向量来得到向量矩阵“ 例如:numpy:如何从矩阵向量构造向量矩阵

matrix1( 
[ 
[1, 2, 3], 
[1, 2, 3], 
[1, 2, 3] 
]) 

matrix2( 
[ 
[2, 4, 6], 
[2, 4, 6], 
[2, 4, 6] 
]) 

--> 

matrix( 
[ 
[array('1 2'), array('2 4'), array('3 6')], 
[array('1 2'), array('2 4'), array('3 6')], 
[array('1 2'), array('2 4'), array('3 6')] 
]) 

我是新来numpy的,所以我不知道这是否是允许把任何东西numpy的的矩阵或只是数字。 它不容易从谷歌得到的答案与类似的“矩阵描述矩阵的向量和向量“

+0

你确定你想要一个实际的NumPy _matrix_而不是一个2d或3d的'np.ndarray'吗?主要区别在于NumPy矩阵的乘法遵循通常的线性代数规则,而如果将两个兼容形状的2d ndarrays相乘,则会得到一个元素乘法。如果你不是线性代数,那么你几乎肯定需要一个ndarray而不是矩阵。 –

+1

你试图解决的大问题是什么?你可以做很多与此大致相似的事情,但我怀疑这不是一个正确的问题。部分难题是numpy没有将“矢量”概念与“矩阵”分开。它确实有“矩阵”和“阵列”的不同概念,但大多数人完全避免了矩阵表示。如果使用数组,则“矢量”,“矩阵”和“张量”的概念都归入数组“形状”属性的一般概念之下。 – senderle

+0

@MarkDickinson我正在尝试做元素明智的线性代数。也就是说,对于最终矩阵的一个元素,例如。 array('1 2'),我想将它乘到一个矩阵('1 0,0 1')并将其乘以另一个数组,例如,转置(array('1 2')) – Hoohoo

回答

0

numpy没有与”矩阵“分开的”向量“的概念。它确实h即“矩阵”和“阵列”的不同概念,但大多数人完全避免了矩阵表示。如果使用数组,则“矢量”,“矩阵”和“张量”的概念都归入数组“形状”属性的一般概念之下。

在这个世界观中,向量和矩阵都是二维数组,仅由它们的形状来区分。行向量是形状为(1, n)的数组,而列向量是形状为(n, 1)的数组。矩阵是形状为(n, m)的阵列。一维数组有时可能会像向量一样表现,这取决于上下文,但是经常会发现,除非您“升级”它们,否则您将无法获得所需的内容。

记住这一切,下面是你的问题的一个可能的答案。首先,我们创建一个一维数组:

>>> a1d = numpy.array([1, 2, 3]) 
>>> a1d 
array([1, 2, 3]) 

现在我们重塑它以创建列向量。 -1这里告诉numpy找出输入的正确大小。

>>> vcol = a1d.reshape((-1, 1)) 
>>> vcol 
array([[1], 
     [2], 
     [3]]) 

观察这个开头和结尾的加括号。这是一个微妙的提示,这是一个二维阵列,即使一个维度的大小只有1个。

我们可以做同样的事情,交换维度,得到一个行。再次注意双括号。

>>> vrow = a1d.reshape((1, -1)) 
>>> vrow 
array([[1, 2, 3]]) 

您可以知道这些是2- d阵列,因为1-d阵列将在其shape元组只有一个值:

>>> a1d.shape 
(3,) 
>>> vcol.shape 
(3, 1) 
>>> vrow.shape 
(1, 3) 

为了建立从我们可以列向量的矩阵使用hstack。还有很多其他方法可能会更快,但这是一个很好的起点。这里请注意,[vcol]不是numpy对象,而是一个普通的python列表,因此[vcol] * 3的含义与[vcol, vcol, vcol]相同。

>>> mat = numpy.hstack([vcol] * 3) 
>>> mat 
array([[1, 1, 1], 
     [2, 2, 2], 
     [3, 3, 3]]) 

vstack给出了与行向量相同的结果。

>>> mat2 = numpy.vstack([vrow] * 3) 
>>> mat2 
array([[1, 2, 3], 
     [1, 2, 3], 
     [1, 2, 3]]) 

这是不可能的“从基质的载体构建载体矩阵”任何其他的解释会产生你真正想要的东西numpy

既然你提到想要做线性代数,这里有几个可能的操作。这假定您使用的是Python的最新足够版本来使用新的@运算符,该运算符为数组的矩阵乘法提供了明确的内联符号。

对于数组,乘法是总是元素明智。但有时候会有广播。对于具有相同的形状的值,这是显而易见的逐元素乘法:

​​

当值具有不同的形状,它们被广播一起如果可能的话,以产生合理的结果:

>>> vrow * vcol 
array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 
>>> vcol * vrow 
array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 

广播工作在你所期望的其它形状的方法:

>>> vrow * mat 
array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 
>>> vcol * mat 
array([[1, 1, 1], 
     [4, 4, 4], 
     [9, 9, 9]]) 

如果你想有一个点的产品,你必须使用@操作:

>>> vrow @ vcol 
array([[14]]) 

注意与*运营商,这是不是对称的:

>>> vcol @ vrow 
array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 

这可有点在第一混乱,因为这看起来一样vrow * vcol,但不要上当。无论参数顺序如何,*都会产生相同的结果。最后,对于一个矩阵矢量乘积:

>>> mat @ vcol 
array([[ 6], 
     [12], 
     [18]]) 

再次观察差@*之间:

>>> mat * vcol 
array([[1, 1, 1], 
     [4, 4, 4], 
     [9, 9, 9]]) 

1.不幸的是,这仅存在像Python 3.5。如果您需要使用较早的版本,则所有相同的建议都适用,除了使用a @ b的内嵌表示法之外,您必须使用np.dot(a, b)numpymatrix类型覆盖*表现得像@ ...但你不能做元素方式乘法或广播相同的方式!因此,即使您有较早版本,我也不建议使用matrix类型。