我有一个numpy数组A,它有形状(10,)。
我也有,截至目前,一个形状为(10,3,5)的numpy数组B.我想在这两者之间进行乘法以得到C,使得C [0,:,] = A [0] * B [0,:,],C [1] = A [1] * B [1 ,:,]]等。
我不想用循环来解决这个问题,其中一个原因是事物的美学,另一个原因是这个代码需要非常通用。我希望用户能够输入任何形状的任何B,只要前导尺寸为10.例如,我希望用户能够放入形状B(10,4)。 / p>
那么:如何使用numpy实现这种乘法?感谢。
ADDENDUM:已经被要求举例。会变小。让我们说A是numpy数组[1,2,3],B是numpy数组[[1,2],[4,5],[7,8]]。我希望两者的乘法得到[[1,2],[8,10],[21,24]]。 ...
>>> a
array([1, 2, 3])
>>> b
array([[1, 2],
[4, 5],
[7, 8]])
>>> #result
>>> c
array([[ 1, 2],
[ 8, 10],
[21, 24]])
>>>
答案 0 :(得分:4)
您可以使用None
(或np.newaxis
)展开A
以匹配B
:
>>> A = np.arange(10)
>>> B = np.random.random((10,3,5))
>>> C0 = np.array([A[i]*B[i,:,:] for i in range(len(A))])
>>> C1 = A[:,None,None] * B
>>> np.allclose(C0, C1)
True
但这只适用于2个案例。从@ajcr借用,有足够的转置,我们可以得到隐式广播,适用于一般情况:
>>> C3 = (A * B.T).T
>>> np.allclose(C0, C3)
True
或者,您可以使用einsum
来提供一般性。回想起来,与转置路线相比,这可能是过度杀伤,但是当乘法更加复杂时,它很方便。
>>> C2 = np.einsum('i,i...->i...', A, B)
>>> np.allclose(C0, C2)
True
和
>>> B = np.random.random((10,4))
>>> D0 = np.array([A[i]*B[i,:] for i in range(len(A))])
>>> D2 = np.einsum('i,i...->i...', A, B)
>>> np.allclose(D0, D2)
True
答案 1 :(得分:1)
虽然我喜欢einsum
符号,但我会添加一些变化......
您可以为a
添加足够的额外维度,以便b
跨>>> a.shape
(3,)
>>> b.shape
(3,2)
。
b
a
的尺寸大于extra_dims = b.ndim - a.ndim
a
将额外维度添加到new_shape = a.shape + (1,)*extra_dims # (3,1)
new_a = a.reshape(new_shape)
new_a * b
乘
def f(a, b):
'''Product across the first dimension of b.
Assumes a is 1-dimensional.
Raises AssertionError if a.ndim > b.ndim or
- the first dimensions are different
'''
assert a.shape[0] == b.shape[0], 'First dimension is different'
assert b.ndim >= a.ndim, 'a has more dimensions than b'
# add extra dimensions so that a will broadcast
extra_dims = b.ndim - a.ndim
newshape = a.shape + (1,)*extra_dims
new_a = a.reshape(newshape)
return new_a * b
作为一项功能:
#home