3

I have a numpy array A of shape(N,2) and a numpy array S of shape(N).

How do I multiply both arrays? Currently I am using this code:

tupleS = numpy.zeros( (N , 2) )
tupleS[:,0] = S
tupleS[:,1] = S
product = A * tupleS

I am a python beginner. Is there a better way to do this?

5 Answers 5

6

Numpy uses row-major order, so you have to explicitly create a column. As in:

>> A = numpy.array(range(10)).reshape(5, 2)
>>> B = numpy.array(range(5))
>>> B
array([0, 1, 2, 3, 4])
>>> A * B
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shape mismatch: objects cannot be broadcast to a single shape
>>> B = B.reshape(5, 1)
>>> B
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> A * B
array([[ 0,  0],
       [ 2,  3],
       [ 8, 10],
       [18, 21],
       [32, 36]])
Sign up to request clarification or add additional context in comments.

1 Comment

It's worth noting that reshape creates a view, not a copy: >>> s = numpy.arange(5); s.reshape(5, 1)[3,0] = 99; repr(s) -> 'array([ 0, 1, 2, 99, 4])'. So you could just do A * B.reshape(5, 1) without altering B.
3

Essentially the same as @senderle's answer, but does not require an in-place manipulation of S. You can get a slice an array in a way that adds axes with the index None and this will multiply them: A * S[:,None].

>>> S = np.arange(5)
>>> S
array([0, 1, 2, 3, 4])
>>> A = np.arange(10).reshape((5,2))
>>> A
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])
>>> S[:,None]
array([[0],
       [1],
       [2],
       [3],
       [4]])
>>> A * S[:,None]
array([[ 0,  0],
       [ 2,  3],
       [ 8, 10],
       [18, 21],
       [32, 36]])

Comments

1

Have you tried this:

product = A * S

3 Comments

+1, using numpy's broadcasting features is always the way to go.
@Stiefel, @MRAB, I think the problem is that you have to reshape S for broadcasting to work.
Right, A*S does not work due to shape mismatch. Reshape is indeed the solution.
1

Al tough the title of your question is slightly misnomer, I think the problem you have encountered is mainly related on the numpy broadcasting rules. Thus the following will not work (as you already have observed):

In []: N= 5
In []: A= rand(N, 2)
In []: A.shape
Out[]: (5, 2)

In []: S= rand(N)
In []: S.shape
Out[]: (5,)

In []: A* S
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (5,2) (5) 

However, now a simple way to make S compatible with broadcasting rules (of element wise product of A* S), is to expand its dimension, like:

In []: A* S[:, None]
Out[]: 
array([[ 0.54216549,  0.04964989],
       [ 0.41850647,  0.4197221 ],
       [ 0.03790031,  0.76744563],
       [ 0.29381325,  0.53480765],
       [ 0.0646535 ,  0.07367852]])

But this is really nothing but syntactical sugar for expand_dims, like:

In []: expand_dims(S, 1).shape
Out[]: (5, 1)

Anyway, I personally prefer this simple hassle free approach:

In []: S= rand(N, 1)
In []: S.shape
Out[]: (5, 1)

In []: A* S
Out[]: 
array([[ 0.40421854,  0.03701712],
       [ 0.63891595,  0.64077179],
       [ 0.03117081,  0.63117954],
       [ 0.24695035,  0.44950641],
       [ 0.14191946,  0.16173008]])

Thus with python; it's more straightforward to be explicit than implicit.

1 Comment

Thanks, I changed the title. Good answer. I accepted senderles answer because it is the simplest. All answer somehow aim to modify the shape to (N,1).
-1

I can think of:

product = A * numpy.tile(S, (2,1)).T

A faster solution might be:

product = [d * S for d in A.T]

though that doesn't get you a numpy array as output, and it's transposed. So to get a similar numpy array (note that this is slower than the first solution):

product = numpy.array([d * S for d in A.T]).T

There's probably a dozen other valid solutions, including better ones than these...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.