元素乘以1D-numpy数组(形状(k,1)或(k,))并且结果具有第一个的形状

时间:2012-04-22 12:48:29

标签: python arrays numpy multiplication

我想实现一个对角矩阵应用函数,该函数首先提供对角d,然后用x进行一堆矩阵向量乘法。当然我不想创建一个实际的矩阵,因为所需要的只是元素向量乘法。

现在,一些用户将提供形状d的对角线(k,),其中一些形状(k,1)。此外,x可以包含(k,)(k,1)形状。我希望apply()方法的行为与numpy矩阵的*一样,因为结果与输入x具有相同的形状。

因此问题:在Python / Numpy中,是否有一种非常不理想的方法来对形状x或{{1}的两个np.arrays y(k,)进行元素乘法运算。 (以任意组合),使得结果数组的形状为(k,1)

我用x

进行了一些实验
[:,None]

我当然可以将我的代码包装在x = np.empty((4,1)) y = np.empty(4) (x * y).shape # (4,4) -- nope (y * y).shape # (4,) -- yes (x * y[:,None]).shape # (4, 1) -- yes (y * y[:,None]).shape # (4,4) -- nope 中,但这并不是非常pythonic。

建议?

2 个答案:

答案 0 :(得分:5)

既然我理解了你的问题,我的建议只是重塑。调用reshape会返回一个视图,因此不会产生任何大的复制成本或类似的事情。只需重新整形数组,再乘以并重新整形:

>>> def shape_preserving_mult(x, y):
...     return (x.reshape((-1,)) * y.reshape((-1))).reshape(x.shape)
... 

或者更简洁,正如你和rroowwllaanndd指出的那样:

>>> def shape_preserving_mult(x, y):
...     return x * y.reshape(x.shape)
... 
>>> shape_preserving_mult(x, y)
array([[ 0],
       [ 1],
       [ 4],
       [ 9],
       [16]])
>>> shape_preserving_mult(x, y.T)
array([[ 0],
       [ 1],
       [ 4],
       [ 9],
       [16]])
>>> shape_preserving_mult(x.T, y)
array([[ 0,  1,  4,  9, 16]])
>>> shape_preserving_mult(x.T, y.T)
array([[ 0,  1,  4,  9, 16]])

我之前建议的内容仍然如下。

值得注意的是,如果你将一个形状(1, 4)的numpy数组与一个形状(4,)的数组相乘,你会得到一些接近你想要的东西。

>>> x = numpy.arange(5).reshape((5, 1))
>>> y = numpy.arange(5)
>>> x.shape
(5, 1)
>>> x.T.shape
(1, 5)
>>> y * x.T
array([[ 0,  1,  4,  9, 16]])

这不具有a的形状,但它的形状为a.T。您可以随时再次对结果调用T。这也适用于形状(5,)的数组,因为1-d数组上的转置操作不会导致任何变化。所以也许你可以这样做:

>>> def transposed_mult(x, y):
...     return (x.T * y).T
... 
>>> transposed_mult(x, y)
array([[ 0],
       [ 1],
       [ 4],
       [ 9],
       [16]])

但是,如果你传递一个形状(1, 5)的数组:

,这当然会导致相反的问题
>>> transposed_mult(x.T, y)
array([[ 0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4],
       [ 0,  2,  4,  6,  8],
       [ 0,  3,  6,  9, 12],
       [ 0,  4,  8, 12, 16]])

因此,transposed_mult完成您在原始帖子中要求的确切内容,但如果您需要任何进一步的灵活性,它将无法按预期工作。事实上,您似乎需要额外的灵活性。

答案 1 :(得分:3)

如果你可以假设xy都是1D数组,那么使用numpy的.flatten()数组方法:

>>> result=x.flatten()*y.flatten()

应该返回一维数组:

>>> result.shape
(4,)

要保留x的形状,您可以执行以下操作:

>>> result = x*y.reshape(x.shape)
>>> result.shape
(4,1)