1
votes
A=np.array([
            [1,2],
            [3,4]
           ])

B=np.ones(2)

A is clearly of shape 2X2

How does numpy allow me to compute a dot product np.dot(A,B)

[1,2]  (dot)  [1,1]
[3,4]

B has to have dimensions of 2X1 for a dot product or rather this

[1,2]  (dot)  [1]
[3,4]         [1]

This is a very silly question but i am not able to figure out where i am going wrong here?

Earlier i used to think that np.ones(2) would give me this:

[1]
[1]

But it gives me this:

[1,1]
3
Are you looking for np.dot(A, B[:,None])? (which returns array([[ 3.], [ 7.]]). - unutbu
No, my question is that np.ones(2), does it give a row vector or a column vector. If i print it out, it is a row vector. If it is a row vector then the dot product between A and B should not be possible - Somye
It is a 1d array. It isn't a row vector. or a 1 row matrix. - hpaulj
Similar question about 1d arrays and matrix multiplication, stackoverflow.com/questions/48492429/… - hpaulj

3 Answers

3
votes

I'm copying part of an answer I wrote earlier today:

You should resist the urge to think of numpy arrays as having rows and columns, but instead consider them as having dimensions and shape. This is an important point which differentiates np.array and np.matrix:

x = np.array([1, 2, 3])
print(x.ndim, x.shape)  # 1 (3,)

y = np.matrix([1, 2, 3])
print(y.ndim, y.shape)  # 2 (1, 3)

An n-D array can only use n integer(s) to represent its shape. Therefore, a 1-D array only uses 1 integer to specify its shape.

In practice, combining calculations between 1-D and 2-D arrays is not a problem for numpy, and syntactically clean since @ matrix operation was introduced in Python 3.5. Therefore, there is rarely a need to resort to np.matrix in order to satisfy the urge to see expected row and column counts.

1
votes

This behavior is by design. The NumPy docs state:

If a is an N-D array and b is a 1-D array, it is a sum product over the last axis of a and b.

0
votes

Most of the rules for vector and matrix shapes relating to the dot product exist mostly in order to have a coherent method that scales up into higher tensor orders. But they aren't very important when dealing with 1st order (vectors) and 2nd order (matrix) tensors. And those orders are what the vast majority of numpy users need.

As a result, @ and np.dot are optimized (both mathematically and input parsing) for those orders, always summing over the last axis of the first and the second to last axis (if applicable) of the second. The "if applicable" is sort of an idiot-proofing to assure the output is what is expected in the vast majority of cases, even if the shapes don't technically fit.

Those of us who use higher-order tensors, meanwhile, are relegated to np.tensordot or np.einsum, which come complete with all the niggling little rules about dimension matching.