2017-03-15 35 views

Odpowiedz

5

outer method z NumPy ufuncs traktuje wejściowych wielowymiarowy, jak chcesz, więc można zrobić

numpy.multiply.outer(a, b) 

zamiast używać numpy.outer.

Wszystkie proponowane tutaj rozwiązania są równie szybkie; dla małych tablic, multiply.outer ma lekką przewagę

enter image description here

kod do generowania obrazu:

import numpy 
import perfplot 


def multiply_outer(data): 
    a, b = data 
    return numpy.multiply.outer(a, b) 


def outer_reshape(data): 
    a, b = data 
    return numpy.outer(a, b).reshape((a.shape + b.shape)) 


def tensor_dot(data): 
    a, b = data 
    return numpy.tensordot(a, b, 0) 


perfplot.show(
     setup=lambda n: (numpy.random.rand(n, n), numpy.random.rand(n, n)), 
     kernels=[multiply_outer, outer_reshape, tensor_dot], 
     n_range=[2**k for k in range(7)], 
     logx=True, 
     logy=True, 
     ) 
2

Jedno podejście byłoby korzystania np.outer a następnie reshape -

np.outer(a,b).reshape((a.shape + b.shape)) 
1

np.einsum jest to, czego szukasz.

c[..., j] == a * b[j]

powinny być

c = np.einsum('...i,j -> ...ij', a, b)

i c[..., i1, i2, i3] == a * b[i1, i2, i3] powinny być

c = np.einsum('i,...jkl -> ...ijkl', a, b)

1

myślę szukasz produktu kroneker

np

> np.kron(np.eye(2), np.ones((2,2))) 

array([[ 1., 1., 0., 0.], 
     [ 1., 1., 0., 0.], 
     [ 0., 0., 1., 1.], 
     [ 0., 0., 1., 1.]]) 
2

myślę np.tensordot działa również

c = np.tensordot(a, b, 0) 

inds = np.reshape(np.indices(b.shape), (b.ndim, -1)) 
for ind in inds.T: 
    ind = tuple(ind) 
    assert np.allclose(a * b[ind], c[(...,) + ind]) 
else: 
    print('no error') 
# no error