dofine
dofine

Reputation: 883

numpy dot product of sub array?

I have two ndarray like

n1 = np.array([1,2,3,4])
n2 = np.array([1,2,3,4])

While dot product of them can done easily with np.dot(n1, n2), which gives 30 as the right answer. What if I need the dot to be operated on two subarrays from n1 and n2, e.g.

np.dot(np.array([1,2]), np.array([1,2]))  # first two elements from arrays
np.dot(np.array([3,4]), np.array([3,4]))  # last two elements

Gives [5, 25]. I could do it by hand split array and for loop. But wondering if there is a more pythonic and numpy way to do this?

Upvotes: 0

Views: 1187

Answers (3)

Divakar
Divakar

Reputation: 221584

Reshape to have two two column arrays, since we want subarrays of length 2 each and then use np.einsum for the sum-reduction -

a = n1.reshape(-1,2)
b = n2.reshape(-1,2)

out = np.einsum('ij,ij->i',a,b)

Another one would be to do element-wise multiplication, then use one reshape and finally sum each row for a compact solution -

out = (n1*n2).reshape(-1,2).sum(1) # 2 is subarray length

Upvotes: 2

Mad Physicist
Mad Physicist

Reputation: 114330

You can perform the dot by manually multiplying and adding the arrays. If you use np.add's reduceat method, you have the flexibility of summing over completely arbitrary intervals:

n = np.add.reduceat(n1 * n2, [0, 2])

If you wanted to have the sum over the first three and the last one element, you would just pass [0, 3] for the indices (the second argument).

If arbitrary length intervals are not interesting to you, use the other answers instead.

Upvotes: 1

hpaulj
hpaulj

Reputation: 231385

Here's one way:

In [124]: n1 = np.array([1,2,3,4])
     ...: n2 = np.array([1,2,3,4])
     ...: 

reshaping splits the arrays in to the desired blocks:

In [125]: n1.reshape(2,2)
Out[125]: 
array([[1, 2],
       [3, 4]])

now multiply all elements together - and sum on the right axis (sometimes I guess as to axis).

In [126]: (n1.reshape(2,2)*n2.reshape(2,2)).sum(axis=1)
Out[126]: array([ 5, 25])

That sum of products can also be expressed with einsum - but don't worry if the syntax is too new:

In [127]: np.einsum('ij,ij->i',n1.reshape(2,2), n2.reshape(2,2))
Out[127]: array([ 5, 25])

Upvotes: 2

Related Questions