我想做这样的事情:
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在那里的特殊问题的性质,讨论非常简短并且被追踪到其他问题。)
答案 0 :(得分:5)
您可以使用numpy的einsum
函数使用爱因斯坦求和符号来执行此操作:
ares = np.einsum('ijkl,k->ijkl', a, v)
答案 1 :(得分:4)
您可以automatically broadcast向量对阵阵列的最外轴。所以,您可以transpose数组将您想要的轴交换到外部,然后将其转换回来:
ares = (a.transpose(0,1,3,2) * v).transpose(0,1,3,2)
答案 2 :(得分:3)
我倾向于做类似
的事情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
答案 3 :(得分:3)
还有一个:
b = a * v.reshape(-1, 1)
恕我直言,这比transpose
,einsum
甚至v[:, None]
更具可读性,但请选择适合您风格的那个。