简体   繁体   中英

Matrix multiplying arrays with Numpy

I have a 5x5 array of arrays and I'm trying to matrix multiply the transpose of one row with another row.

import numpy as np
a = np.array([1, 4, 6, 4, 1])
b = np.array([-1, -2, 0, 2, 1])
c = np.array([-1, 2, 0, -2, 1])
d = np.array([-1, 0, 2, 0, -1])
e = np.array([1, -4, 6, -4, 1]) 
f = np.vstack([a, b, c, d, e])

result = np.dot(f[1, :].T, f[1, :])

I assumed this would work but apparently

f[1, :].T

ends up becoming

[-1, -2, 0, 2, 1]

rather than

[[-1]
 [-2]
 [ 0]
 [ 2]
 [ 1]]

and so np.dot treats it like a real dot product rather than doing matrix multiplication.

I found out that list slicing where one index is an integer and all others are : s reduces the dimension by one so so the shape of f[1, :] is not (1, 5) but (5,) and so transposing it does nothing.

I've been able to get it to working using f[1, :].reshape((1, 5)) but is there a better way of doing this? Am I missing a simple way of getting the transpose without having to reshape it?

You can use np.newaxis to add a dimension when slicing, to compensate for the dimension that is otherwise lost.

f[1, :, np.newaxis]

produces the single-column 2D array you want. Putting np.newaxis before the colon would give a single-row 2D array.

For numpy arrays it is often favorable to have this behavior, to circumvent this you can always use the numpy matrix class.

>>> f = np.matrix(f)
>>> f
matrix([[ 1,  4,  6,  4,  1],
        [-1, -2,  0,  2,  1],
        [-1,  2,  0, -2,  1],
        [-1,  0,  2,  0, -1],
        [ 1, -4,  6, -4,  1]])

>>> f[1,:].T
matrix([[-1],
        [-2],
        [ 0],
        [ 2],
        [ 1]])

>>> np.dot(f[1, :].T, f[1, :])
matrix([[ 1,  2,  0, -2, -1],
        [ 2,  4,  0, -4, -2],
        [ 0,  0,  0,  0,  0],
        [-2, -4,  0,  4,  2],
        [-1, -2,  0,  2,  1]])

As this is the matrix class * will denote matrix multiplication, therefore you can simply use:

f[1,:].T * f[1,:]

Also you may want to consider np.outer for this kind of operation:

>>> np.outer(f[1,:],f[1,:])
array([[ 1,  2,  0, -2, -1],
       [ 2,  4,  0, -4, -2],
       [ 0,  0,  0,  0,  0],
       [-2, -4,  0,  4,  2],
       [-1, -2,  0,  2,  1]])

If you want the individual slices to retain their "matrixness" then you should cast f to a numpy.matrix, which preserves the matrixness.

 fm = numpy.matrix(f)

then

numpy.dot(fm[1,:].T,fm[1,:])

will return an nxn matrix

Following the accepted answer, I prefer to use None instead of np.newaxis , which is a little verbose for my tastes. For example,

f[:,None]

does the same thing as f[:,np.newaxis] .

I am late to the party here, it is worth noting that the NumPy webpage I accessed today warns that

class numpy.matrix(data, dtype=None, copy=True)

might be removed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM