Извините за некромантию, но этот ответ можно существенно улучшить, используя бесценный np.einsum.
import numpy as np
D,M,N,R = 1,2,3,4
A = np.random.rand(M,N,R)
B = np.random.rand(N,D,R)
print np.einsum('mnr,ndr->mdr', A, B).shape
Обратите внимание, что у него есть несколько преимуществ: прежде всего, это быстрый.np.einsum в целом хорошо оптимизирован, но, кроме того, np.einsum достаточно умен, чтобы избежать создания временного массива MxNxR, но выполняет сжатие непосредственно над N.
Но, что еще важнее, он очень читабелен,Нет сомнений в том, что этот код правильный;и вы могли бы сделать все намного сложнее без каких-либо проблем.
Обратите внимание, что фиктивная ось 'D' может быть просто удалена из B и оператора einsum, если вы хотите.