import numpy
a = numpy.arange(9).reshape(3,3)
b = numpy.arange(60).reshape(20,3)
c1 = numpy.dot(b, a.T) # as in the answer of senderle
c2 = numpy.einsum('ji,ki->kj',a,b)
and the resulting c1 and c2 are both the same as what you wish (verified with your c[i] = np.dot(a, b[i])
)
the advantage of numpy.einsum
is that this trick 'ji,ki->kj'
telling what has to be done on what dimension also works for larger dimensions.
more explanation on einsum
for example, if you want to do the following operation:
a = numpy.arange(60.).reshape(3,4,5)
b = numpy.arange(24.).reshape(4,3,2)
d1 = numpy.zeros((5,2))
for i in range(5):
for j in range(2):
for k in range(3):
for n in range(4):
d1[i,j] += a[k,n,i] * b[n,k,j]
you can do the same thing much faster by doing:
d2 = numpy.einsum('kni,nkj->ij', a, b)
# the 'kni,nkj->ij' is what you otherwise do with the indices as in
# d1[i,j] += a[k,n,i] * b[n,k,j]
or if you do not like this way of specifying what has to happen, you can also use numpy.tensordot
instead of numpy.einsum
, and specify the axes as follows:
d3 = numpy.tensordot(a,b, axes=([1,0],[0,1]))
so this einsum method is very general and can be used to shortcut for-loops (that are otherwise slow, if you do them in python), and are very interesting for funky tensor-stuff
for more info, see http://docs.scipy.org/doc/numpy/reference/generated/numpy.tensordot.html and http://docs.scipy.org/doc/numpy/reference/generated/numpy.einsum.html