How to multiply specific rows/columns of matrices with each other in python?

By default, numpy gets rid of the singleton dimension, as you have noticed.
You can use np.newaxis (or equivalently None. That is an implementation detail, but also works in pytorch) for the second axis to tell numpy to "invent" a new one.

import numpy as np
a = np.ones((3,3))
a[1].shape                 # this is (3,)
a[1,:].shape               # this is (3,)
a[1][...,np.newaxis].shape # this is (3,1)

However, you can also use dot or outer directly:

>>> a = np.eye(3)
>>> np.outer(a[1], a[1])
array([[0., 0., 0.],
       [0., 1., 0.],
       [0., 0., 0.]])
>>> np.dot(a[1], a[1])
1.0

Generally, I would recommend using np.einsum for most matrix operations as it very elegant. To obtain a the row-wise outer product of the vectors contained in m1 and m2 of shape (n, 3) you could do the following:

import numpy as np
m1 = np.array([1, 2, 3]).reshape(1, 3)
m2 = np.array([1, 2, 3]).reshape(1, 3)
result = np.einsum("ni, nj -> nij", m1, m2)
print(result)
>>>array([[[1, 2, 3],
        [2, 4, 6],
        [3, 6, 9]]])