Create array of outer products in numpy

2020-02-16 02:59发布

I have an array of n vectors of length m. For example, with n = 3, m = 2:

x = array([[1, 2], [3, 4], [5,6]])

I want to take the outer product of each vector with itself, then concatenate them into an array of square matrices of shape (n, m, m). So for the x above I would get

array([[[ 1,  2],
        [ 2,  4]],

       [[ 9, 12],
        [12, 16]],

       [[25, 30],
        [30, 36]]])

I can do this with a for loop like so

np.concatenate([np.outer(v, v) for v in x]).reshape(3, 2, 2)

Is there a numpy expression that does this without the Python for loop?

Bonus question: since the outer products are symmetric, I don't need to m x m multiplication operations to calculate them. Can I get this symmetry optimization from numpy?

2条回答
够拽才男人
2楼-- · 2020-02-16 03:22

I used the following snippet when I was trying to do the same in Theano:

def multiouter(A,B):
'''Provided NxK (Theano) matrices A and B it returns a NxKxK tensor C with C[i,:,:]=A[i,:]*B[i,:].T'''
return A.dimshuffle(0,1,'x')*B.dimshuffle(0,'x',1)

Doing a straighforward conversion to Numpy yields

def multiouter(A,B):
'''Provided NxK (Numpy) arrays A and B it returns a NxKxK tensor C with C[i,:,:]=A[i,:]*B[i,:].T'''
return A[:,:,None]*B[:,None,:]

I think I got the inspiration for it from another StackOverflow posting, so I am not sure I can take all the credit.

Note: indexing with None is equivalent to indexing with np.newaxis and instantiates a new axis with dimension 1.

查看更多
爷、活的狠高调
3楼-- · 2020-02-16 03:32

Maybe use einsum?

>>> x = np.array([[1, 2], [3, 4], [5,6]])
>>> np.einsum('ij...,i...->ij...',x,x)
array([[[ 1,  2],
        [ 2,  4]],

       [[ 9, 12],
        [12, 16]],

       [[25, 30],
        [30, 36]]])
查看更多
登录 后发表回答