Domanda

I have two one-d numpy arrays in files.

'test1'=(2,3)

'test2'=(5,6,7)

I would like to multiply them together to get

t=(10, 12, 14, 15, 18, 21)

I am using this program

import numpy as np

a=open('test1')
b=open('test2')
c=open('test3','w+')
t1=np.loadtxt(a)
t2=np.loadtxt(b)
t=t1*t2

print >> c, t

When I run the program, I get the following error..

ValueError: operands could not be broadcast together with shapes (2) (3)

What should I do to get the desired result?

È stato utile?

Soluzione

Using numpy.outer and numpy.ravel

>>> import numpy as np
>>> a = np.array((2,3))
>>> b = np.array((5,6,7))
>>> np.outer(a,b).ravel()
array([10, 12, 14, 15, 18, 21])

Edit:

Subraction: we can't use numpy.outer, but we can use numpy.newaxis:

>>> (a[:, np.newaxis] - b).ravel()
array([-3, -4, -5, -2, -3, -4])

Altri suggerimenti

You could make use of the broadcasting functionality. This is a very powerful concept, that opend many doors to me once i understood it. The idea is that numpy does simple operations (+,-,*,/ etc.) element by element if you use it in combinations with two arrays. This means, that of course thy must have the same shape (same number of elements in each dimension). for example A.shape == (3,4) and B.shape == (3,4) you can do A*B and get in new array of the same shape where each element is the product of the elements in A and B at the same indexes.

a = ones((3,4))*2
b = ones((3,4))*3
c = a*b
print c.shape
> (3,4)

From that rule there is a smart exception: Whenever an array has only one element in a dimension certain dimension then it is broadcasted. This means this one dimension will be "blown up" along this axis with as many identical copies as needed to be compatible with the other array.

a = ones((3,4))*2
b = ones((1,4))*3
c = a*b
print c.shape
> (3,4)

Ok, for your problem you can use that by adding a dimensions into your arrays: so you had a.shape = (2,) you want to get (2,1) and b.shape = (3,) you want (1,3) so that is you use an operation on them it will be broadcasted so each element from a will be multiplied with each element from b. you do this by adding np.newaxis into your array

a = np.array((2,3))[:,np.newaxis]
b = np.array((5,6,7))[np.newaxis,:]
print a.shape 
> (2,1)
print b.shape
> (1,3)
c = a*b
> (2,3)

now you will get an array of the shape (2,3) but you wanted a 1d array, so you can use flatten() to sum up:

a = np.array((2,3))[:,np.newaxis]
b = np.array((5,6,7))[np.newaxis,:]
c = (a[:,np.newaxis]*b[np.newaxis,:]).flatten()

I wonder why you think t1*t2 would produce what you want?

If I wrote:

[x,y,z]*[a,b]

what would you say the answer is? Why?

Some possiblities:

[x*a, y*b, z*??]
[x*???, y*a, z*b]
[[x*a, y*a, z*a],[x*b,y*b,z*b]]
[[x*a, x*b],[y*a, y*b],[z*a,z*b]]
[x*a, y*a, z*a, x*b, y*b, z*b]
etc

The multiple ways of mixing and matching 2 lists of numbers. To put it simply, numpy tries the first, element by element match, and complains because it does not know what to do with the unmatched z.

Here's another way of producing the 'flat' outer product:

(t1.reshape(2,1)*t2).reshape(6)

In a Python shell, try this (and the other suggestions) in pieces to better understand what is going on.

Before the final reshape this produces a 2D matrix. This is key to understanding how you want to combine the 2 vectors.

array([[10, 12, 14],
       [15, 18, 21]])
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top