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

Nic*_*mer 4 python arrays numpy multiplication

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

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

因此问题是:在Python/Numpy中,是否有一种非常不经常的方法来元素乘法两个np.arrays xy形状(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
Run Code Online (Sandbox Code Playgroud)

我当然可以将我的代码包装进去if len(x.shape)==...:,但这并不是非常pythonic.

建议?

sen*_*rle 5

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

>>> def shape_preserving_mult(x, y):
...     return (x.reshape((-1,)) * y.reshape((-1))).reshape(x.shape)
... 
Run Code Online (Sandbox Code Playgroud)

或者更简洁,正如你和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]])
Run Code Online (Sandbox Code Playgroud)

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

值得注意的是,如果你将一个numpy形状(1, 4)的数组与一个形状数组相乘,(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]])
Run Code Online (Sandbox Code Playgroud)

这不具有形状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]])
Run Code Online (Sandbox Code Playgroud)

但是,如果传递一个形状数组,这当然会导致相反的问题(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]])
Run Code Online (Sandbox Code Playgroud)

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