我想实现一个对角矩阵应用函数,该函数首先提供对角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。
建议?
答案 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)
如果你可以假设x
和y
都是1D数组,那么使用numpy的.flatten()
数组方法:
>>> result=x.flatten()*y.flatten()
应该返回一维数组:
>>> result.shape
(4,)
要保留x
的形状,您可以执行以下操作:
>>> result = x*y.reshape(x.shape)
>>> result.shape
(4,1)