A row vector in classic linear algebra such as (1, -2, 10, 9, 5, -4) can be expressed in Numpy as,

```
v1_row = np.array([1,-2,10,9,5,-4])[None,:]
```

Is this an authentic row vector? Yes, as can be shown by getting its shape:

```
v1_row.shape
```

There you have it. This is a 1 X 6 array, or simply a row vector.

Similarly, to get a column vector we can say,

```
v2_col = np.array([6,-2,-8,4,2,0])[:,None]
v2_col.shape
```

This is a 6 X 1 array or a column vector with 6 rows. So why do we need the [None,:] and [:,None] to get “authentic” row and column vectors? That question can be easily answered by…

```
v3 = np.array([1,-2,10,9,5,-4])
print('V3: ',v3.shape)
```

v3 is not a column vector in the classical sense. The vector v2_col is a genuine, honest column vector.

I can even use the transpose operator on v2_col to get v4_row:

```
v4_row = v2_col.T
print(type(v4_row))
v4_row.shape
```

So what happens when I try to do the same thing with our bogus v3 vector:

```
v5 = v3.T
print(type(v5))
print('V5: ',v5.shape)
```

Nothing. Both v5 and v4_row are official, card carrying members of the ‘numpy.ndarray’ class. But they are not the same type of beast when it comes to transposing. What is the lesson? If you want column or row vectors, then declare them as such as shown previously or easier still use the method below.

```
v6_row = np.random.rand(1,25) # 1 row and 25 columns
v7_col = np.random.rand(25,1) # 25 rows and 1 column
```

We can even multiply them in the proper order to get a square array 25 X 25:

```
rnd_array = v7_col * v6_row
print('Shape: ',rnd_array.shape)
print('Size: ',rnd_array.size)
```

Jupyter Notebook: Row_and_Column_Vectors