Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy: multiply arbitrary shape array along first axis

Tags:

python

numpy

I want to multiply an array along it's first axis by some vector.

For instance, if a is 2D, b is 1D, and a.shape[0] == b.shape[0], we can do:

a *= b[:, np.newaxis]

What if a has an arbitrary shape? In numpy, the ellipsis "..." can be interpreted as "fill the remaining indices with ':'". Is there an equivalent for filling the remaining axes with None/np.newaxis?

The code below generates the desired result, but I would prefer a general vectorized way to accomplish this without falling back to a for loop.

from __future__ import print_function

import numpy as np


def foo(a, b):
    """
    Multiply a along its first axis by b
    """
    if len(a.shape) == 1:
        a *= b
    elif len(a.shape) == 2:
        a *= b[:, np.newaxis]
    elif len(a.shape) == 3:
        a *= b[:, np.newaxis, np.newaxis]
    else:
        n = a.shape[0]
        for i in range(n):
           a[i, ...] *= b[i]          

n = 10
b = np.arange(n)

a = np.ones((n, 3))
foo(a, b)
print(a)

a = np.ones((n, 3, 3))
foo(a, b)
print(a)
like image 916
Rob Falck Avatar asked Dec 14 '25 10:12

Rob Falck


1 Answers

Just reverse the order of the axes:

transpose = a.T
transpose *= b

a.T is a transposed view of a, where "transposed" means reversing the order of the dimensions for arbitrary-dimensional a. We assign a.T to a separate variable so the *= doesn't try to set the a.T attribute; the results still apply to a, since the transpose is a view.

Demo:

In [55]: a = numpy.ones((2, 2, 3))

In [56]: a
Out[56]: 
array([[[1., 1., 1.],
        [1., 1., 1.]],

       [[1., 1., 1.],
        [1., 1., 1.]]])

In [57]: transpose = a.T

In [58]: transpose *= [2, 3]

In [59]: a
Out[59]: 
array([[[2., 2., 2.],
        [2., 2., 2.]],

       [[3., 3., 3.],
        [3., 3., 3.]]])
like image 89
user2357112 supports Monica Avatar answered Dec 16 '25 00:12

user2357112 supports Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!