9

我想做这样的事情:

a =  # multi-dimensional numpy array
ares = # multi-dim array, same shape as a
a.shape
>>> (45, 72, 37, 24)  # the relevant point is that all dimension are different
v = # 1D numpy array, i.e. a vector
v.shape
>>> (37)  # note that v has the same length as the 3rd dimension of a
for i in range(37):
    ares[:,:,i,:] = a[:,:,i,:]*v[i]

我认为必须有一种更紧凑的方式来使用 numpy 执行此操作,但我还没有弄清楚。我想我可以复制 v 然后计算a*v,但我猜还有比这更好的东西。所以我需要“在给定的轴上”进行元素乘法,可以这么说。有谁知道我该怎么做?谢谢。(顺便说一句,我确实发现了一个重复的问题,但由于 OP 的特殊问题的性质,讨论非常简短,并被跟踪到其他问题。)

4

4 回答 4

5

这里还有一个:

b = a * v.reshape(-1, 1)

恕我直言,这比transposeeinsum甚至可能更具可读性v[:, None],但请选择适合您风格的。

于 2013-10-15T18:24:07.943 回答
5

您可以针对数组的最外轴自动广播向量。因此,您可以转置数组以将您想要的轴交换到外部,相乘,然后将其转回:

ares = (a.transpose(0,1,3,2) * v).transpose(0,1,3,2)
于 2013-10-15T18:18:36.130 回答
5

您可以使用 numpy 的einsum函数使用 Einstein 求和符号来做到这一点:

ares = np.einsum('ijkl,k->ijkl', a, v)
于 2013-10-15T18:21:54.447 回答
4

我倾向于做类似的事情

b = a * v[None, None, :, None]

我认为我应该正式写np.newaxis而不是None.

例如:

>>> import numpy as np
>>> a0 = np.random.random((45,72,37,24))
>>> a = a0.copy()
>>> v = np.random.random(37)
>>> for i in range(len(v)):
...     a[:,:,i,:] *= v[i]
...     
>>> b = a0 * v[None,None,:,None]
>>> 
>>> np.allclose(a,b)
True
于 2013-10-15T18:22:07.963 回答