1

I want to multiply two numpy arrays with different shapes. The result should be broadcasted in such a way that e.g. the multiplication of arrays with shape (3,) and (5,) returns an array with shape (3,5). I know that this is possible using array1[:,numpy.newaxis]*array2[numpy.newaxis,:]. But what I am looking for is something more general, a function that does also automatically multiply the arrays with shapes (3,5) and (4,) to an array with shape (3,5,4). Is there any numpy function to do this? Sure, a can write myself a function but is there any function existing?

So I am looking for a function numpy.func(array1, array2) that does return an array array3 with shape (*array1.shape, *array2.shape) and values array3[i1,j1,..,i2,j2,..] = array1[i1,j1,...]*array2[i2,j2,...].

Thanks

  • Why not demonstrate what you want with actual input arrays and the expected output? That's orders of magnitude more-effective than just verbalising the requirements – roganjosh May 15 '20 at 13:48
  • That's broadcasting with different rules. – hpaulj May 15 '20 at 13:54
  • You can use `a[..., None] * b` which works in both cases. – V. Ayrat May 15 '20 at 13:57
  • See `np.einsum`. For instance, you can look at the very last example in [this answer](https://stackoverflow.com/a/33641428/525169). – Praveen May 15 '20 at 14:13
  • Does this answer your question? [Understanding NumPy's einsum](https://stackoverflow.com/questions/26089893/understanding-numpys-einsum) – Praveen May 15 '20 at 14:13
  • Yes, but not in the case np.ones((2,3,4))[...,None] * np.ones((5,6)) – maximumphysics May 15 '20 at 14:14
  • Try `np.einsum('ijk,lm->ijklm', np.ones((2, 3, 4)), np.ones((5, 6)))` – Praveen May 15 '20 at 14:25
  • Yes, thanks @Praveen. I just need a further generalization so that I don't have to give np.einsum the dimensions of the arrays. Your example is perfectly fine, but I don't want to manually handle with the dimensions using ijk for dimension 3 and lm for dimension 2. – maximumphysics May 15 '20 at 14:26
  • The numpy broadcasting rules add extra dimensions at the start as needed, but you have to explicitly add trailing ones. This avoids ambiguities. For example when adding a (3,) to a (2,), should the result be (3,2) or (2,3)? There are programmable ways of adding trailing dimensions, but you need to define the rule clearly. – hpaulj May 15 '20 at 15:27

1 Answers1

1

Take a look at numpy.multiply.outer. outer is a standard method that all the "ufuncs" have.

For example,

In [19]: a   # a has shape (3, 4)
Out[19]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [20]: b   # b has shape (5,)
Out[20]: array([0, 1, 2, 3, 4])

In [21]: c = np.multiply.outer(a, b)

In [22]: c.shape
Out[22]: (3, 4, 5)

In [23]: c[1, 2, 3]
Out[23]: 18

In [24]: a[1, 2]*b[3]
Out[24]: 18
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214