3

I am trying to find the numpy matrix operations to get the same result as in the following for loop code. I believe it will be much faster but I am missing some python skills to do it.

It works line by line, each value from a line of x is multiplied by each value of the same line in e and then summed.

The first item of result would be (2*0+2*1+2*4+2*2+2*3)+(0*0+...)+...+(1*0+1*1+1*4+1*2+1*3)=30

Any idea would be much appreciated :).

e = np.array([[0,1,4,2,3],[2,0,2,3,0,1]])
x = np.array([[2,0,0,0,1],[0,3,0,0,4,0]])
result = np.zeros(len(x))
for key, j in enumerate(x):
    for jj in j:
        for i in e[key]:
            result[key] += jj*i
>>> result
Out[1]: array([ 30.,  56.])
Divakar
  • 218,885
  • 19
  • 262
  • 358
Daerken
  • 33
  • 5

2 Answers2

1

Those are ragged arrays as they have lists of different lengths. So, a fully vectorized approach even if possible won't be straight-forward. Here's one using np.einsum in a loop comprehension -

[np.einsum('i,j->',x[n],e[n]) for n in range(len(x))]

Sample run -

In [381]: x
Out[381]: array([[2, 0, 0, 0, 1], [0, 3, 0, 0, 4, 0]], dtype=object)

In [382]: e
Out[382]: array([[0, 1, 4, 2, 3], [2, 0, 2, 3, 0, 1]], dtype=object)

In [383]: [np.einsum('i,j->',x[n],e[n]) for n in range(len(x))]
Out[383]: [30, 56]

If you are still feel persistent about a fully vectorized approach, you could make a regular array with the smaller lists being filled zeros. For the same, here's a post that lists a NumPy based approach to do the filling.

Once, we have the regular shaped arrays as x and e, the final result would be simply -

np.einsum('ik,il->i',x,e)
Community
  • 1
  • 1
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

Is this close to what you are looking for?

https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html

It seems like you are trying to get the dot product of matrices.

Dakota Dutko
  • 41
  • 1
  • 5