2

I have to matrices:

a = np.array([[6],[3],[4]])
b = np.array([1,10])

when I do:

c = a * b

c looks like this:

[ 6, 60]
[ 3, 30]
[ 4, 40]

which is good. now, lets say I add a column to a (for the sake of the example its an identical column. but it dosent have to be):

a = np.array([[6,6],[3,3],[4,4]])

b stayes the same.

the result I want is 2 identical copies of c (since the column are identical), stacked along a new axis:

new_c.shape == [3,2,2]

when if u do new_c[:,:,0] or new_c[:,:,1] you get the original c. I tried adding new axes to both a and b using np.expand_dims but it did not help.

talonmies
  • 70,661
  • 34
  • 192
  • 269
Moran Reznik
  • 1,201
  • 2
  • 11
  • 28
  • First case a (3,1) * (2,) => (3,2). 2nd, (3,2)*(2,)=>(3,2)*(1,2)=>(3,2). You want (3,2,1)*(1,1,2)=(3,2,2). `a[:,:,None]` should do the trick. – hpaulj Dec 29 '19 at 11:26
  • or maybe its (3,1,n)*(1,2,1)>(3,2n) a[:,None,:]*b[None,2,None] – hpaulj Dec 29 '19 at 11:31

2 Answers2

1

One way is using numpy.einsum:

>>> import numpy as np
>>> a = np.array([[6],[3],[4]])
>>> b = np.array([1,10])
>>> print(a * b)
[[ 6 60]
 [ 3 30]
 [ 4 40]]
>>> print(np.einsum('ij, j -> ij', a, b))
[[ 6 60]
 [ 3 30]
 [ 4 40]]
>>> a = np.array([[6,6],[3,3],[4,4]])
>>> print(np.einsum('ij, k -> ikj', a, b)[:, :, 0])
>>> print(np.einsum('ij, k -> ikj', a, b)[:, :, 1])
[[ 6 60]
 [ 3 30]
 [ 4 40]]
[[ 6 60]
 [ 3 30]
 [ 4 40]]

For more usage about numpy.einsum, I recommend:

Understanding NumPy's einsum

Xinyu Chen
  • 11
  • 4
0

You have multiple options here, one of which is using numpy.einsum as explained in the other answer. Another possibility is using array reshape method:

result = a.T.reshape((a.shape[1], a.shape[0], 1)) * b
result = result.reshape((-1, 2))
result 
array([[ 6, 60],
       [ 3, 30],
       [ 4, 40],
       [ 6, 60],
       [ 3, 30],
       [ 4, 40]])

Yet what is more intuitive to me is to stack arrays by mean of np.vstack with each column of a multiplied by b as follows:

result = np.vstack([c[:, None] * b for c in a.T])
result
array([[ 6, 60],
       [ 3, 30],
       [ 4, 40],
       [ 6, 60],
       [ 3, 30],
       [ 4, 40]])
FBruzzesi
  • 6,385
  • 3
  • 15
  • 37