Let me first understand how the dot operation is defined in numpy.
(for simplicity, leave the rules for discussion out of context) you can perform dot(A,B) if the last dimension A (ie A.shape[-1] ) matches the next last size B (i.e. B . shape [-2]) if B.ndim> = 2 and just dimension B if B.ndim == 1.
In other words, if A.shape=(N1,...,Nk,X) and B.shape=(M1,...,M(j-1),X,Mj) (note the general X ). The resulting array will have the form (N1,...,Nk,M1,...,Mj) (note that X been deleted).
Or, if A.shape=(N1,...,Nk,X) and B.shape=(X,) . The resulting array will have the form (N1,...,Nk) (note that X been deleted).
Your examples work because they satisfy the rules (the first example satisfies the first, the second satisfies the second):
a=numpy.asarray([[1,2,3], [4,5,6], [7,8,9]]) b=numpy.asarray([[2],[1],[3]]) a.shape, b.shape, '->', a.dot(b).shape # X=3 => ((3, 3), (3, 1), '->', (3, 1)) b=numpy.asarray([2,1,3]) a.shape, b.shape, '->', a.dot(b).shape # X=3 => ((3, 3), (3,), '->', (3,))
My recommendation is that when using numpy, don’t think in terms of “row / column vectors” and, if possible, don’t think in terms of “vectors” in general, but in terms of an “array with shape S”. This means that both row vectors and column vectors are simply “1dim arrays”. As for numpy, they are one and the same.
This should also make it clear why in your case b.transponse() is the same as b . b is a 1dim array, when transposed , remains a 1dim array. Transpose does not affect 1dim arrays.