numpy数组乘法与任意维度的数组

时间:2015-08-24 18:26:48

标签: python arrays numpy multiplication

我有一个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]])
>>>

2 个答案:

答案 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