To my understanding, Numpy doesn’t really have a solid definition of “row” and “column”. At best you can look at how they are printed by default, where an array like `a = np.array([4, 5, 6])`

with shape: `(3,)`

will print as:

```
[4 5 6]
```

so I guess you could consider it a “row vector”. What matters for things like `@`

is the relative shape of the two objects.

If you want two objects to be distinct in shape, the common way it to make two matrices, one that is 1×10 and one that is 10×1. To turn an array, `a`

, of shape `(10,)`

into one of `(10,1)`

you can do `a[:, np.newaxis]`

(or to turn it into `(1, 10)`

you can do `a[np.newaxis, :]`

).

As it happens, you can use some of the automatic features of the `@`

operator, which for numpy is defined at numpy.matmul. One of the key points there are under the “Notes” where it says:

- If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
- If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.

and so you perhaps don’t need to actually do any shape conversions in the case where you, for example, have two vectors you want to `@`

together.

Furthermore, I checked and pandas `Series`

can be `@`

directly, without having to convert them to numpy, so you can do:

```
>>> a = np.array([4, 5, 6])
>>> s = pd.Series([1, 2, 3])
>>> a @ s
32
```