Artimi
Artimi

Reputation: 351

Multiple arrays tensordot

I've got list of np.arrays like:

l = [array([0.2,0.3,0.5]),array([0.7,0.3])]

What I need to get outer product:

array([[0.14, 0.06],
       [0.21, 0.09],
       [0.35, 0.15]])

in general way:

array([[l[0][0] * l[1][0], l[0][0] * l[1][1]],
       [l[0][1] * l[1][0], l[0][1] * l[1][1]],
       [l[0][2] * l[1][0], l[0][2] * l[1][1]]])

But for any length of l (>= 2), so when len(l) == 4, I'll got 4-dimensional array.

My current approach is to use tensordot in for loop:

product = np.tensordot(l[0], l[1], 0)
for i in range(2, len(l)):
    product = np.tensordot(product, l[i], 0)

But I'm used that in Python code looks nicer. Have anybody some idea how to do nicer and faster solution?

The motive is that I need to get sum of element-wise multiplied two arrays:

result = np.sum(arr * product)

where arr.shape == product.shape. Maybe you, clever guys, can improve it also.

Upvotes: 2

Views: 514

Answers (2)

Ryan Saxe
Ryan Saxe

Reputation: 17869

numpy has a great thing called broadcasting, where it iterates through the arrays. so if you have an array that is x by 1 and multiply it by an array that is 1 by y, you'll get an x by y array. works just like matrices. So I am going to do everything you want in just 2 lines:

result = np.array((l[0])).reshape((1,len(l[0])))# resizing the first column to make it a 3 by 1 so that numpy broadcasting will work.
print result * l[1] # broadcasting the 3 by 1 by a 1 by 2 to result in your 3 by 2 

And there you have it! quick and easy! I am going to put the entire code below for your convenience:

import numpy as np
l = [([0.2,0.3,0.5]),([0.7,0.3])]
result = np.array((l[0])).reshape((len(l[0]),1))
print result * l[1]
>>>>aray([[ 0.14  0.06]
 [ 0.21  0.09]
 [ 0.35  0.15]])

Upvotes: 0

YXD
YXD

Reputation: 32521

Perhaps more concise is:

reduce(lambda x, y: tensordot(x, y, 0), l)

Upvotes: 2

Related Questions