1

У меня есть два 3dim матрицы Numpy, и я хочу сделать скалярное произведение в соответствии с одной оси, без использования цикла:NumPy 3D скалярное произведение

a=[ [[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]], 
    [[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]], 
[ [ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]], 
[ [ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]], 
[[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]], 
[[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0.]], 
[[ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 
    [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 
    [ 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
    [ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0]]] 

b=[[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]], 
[[ 0, 0, 1, 0, 0.], 
    [ 1, 0, 0, 0, 0.], 
    [ 0, 0, 0, 0, 0.], 
    [ 0, 1, 0, 0, 0.]]] 
dt = np.dtype(np.float32) 
a=np.asarray(a,dtype=dt) 
b=np.asarray(b,dtype=dt) 
print(a.shape) 
print(b.shape) 

а имеет форму (7, 4, 15) и b имеет форму (7, 4, 5). Я хочу с = np.dot (а, Ь) в размере (7,5,15), как показано ниже:

c = np.zeros((7,15,5)) 
for i in range(7): 
    c[i,:,:] = np.dot(a[i,:,:].T , b[i,:,:]) 

Но я ищу решение без для петли. что-то вроде:

c = np.tensordot(a.reshape(4,7,5),b.reshape(7,4,15),axes=([1,0],[0,1])) 

но этот не работает должным образом.

Я также попытался это:

newaxes_a=[2,0,1] 
newaxes_b=[1,0,2] 

newshape_a=(-1,28) 
newshape_b=(28,-1) 
a_t = a.transpose(newaxes_a).reshape(newshape_a) 
b_t = b.transpose(newaxes_b).reshape(newshape_b) 
c = np.dot(a_t, b_t) 

, который не работает, как ожидалось.

Любые идеи?

+0

Что плохого для цикла? Если вы работаете с numpy с оптимизированным BLAS, это - скоростная версия, опубликованная до сих пор. – Daniel

+0

@Ophion На самом деле, я ищу решение на основе Anano в конце. Я ответил на ваш комментарий в другом связанном мне вопросе. – PickleRick

ответ

4

Вы можете использовать np.einsum -

#to match the given example 
c2 = np.einsum('ijk,ijl->ikl',a,b) 
print np.allclose(c, c2) 

Еще один использованием broadcasting -

c = (a[:,:,None,:]*b[...,None]).sum(1) 
+0

oh ... отлично! :) Есть ли эквивалентная функция и в анано? Мне также нужно реализовать его в анано. – PickleRick

+0

@Anxam Как насчет трансляции на анано? Посмотрите решение на основе этого. – Divakar

+0

Решение предоставлено здесь: http://stackoverflow.com/questions/30305891/convert-einsum-comput-to-dot-product-to-be-used-in-theano Но я не уверен, что это будет работайте для меня или нет. – PickleRick

Смежные вопросы