numpy divide along axis

user545424 picture user545424 · Aug 21, 2011 · Viewed 26.7k times · Source

Is there a numpy function to divide an array along an axis with elements from another array? For example, suppose I have an array a with shape (l,m,n) and an array b with shape (m,); I'm looking for something equivalent to:

def divide_along_axis(a,b,axis=None):
    if axis is None:
        return a/b
    c = a.copy()
    for i, x in enumerate(c.swapaxes(0,axis)):
        x /= b[i]
    return c

For example, this is useful when normalizing an array of vectors:

>>> a = np.random.randn(4,3)
array([[ 1.03116167, -0.60862215, -0.29191449],
       [-1.27040355,  1.9943905 ,  1.13515384],
       [-0.47916874,  0.05495749, -0.58450632],
       [ 2.08792161, -1.35591814, -0.9900364 ]])
>>> np.apply_along_axis(np.linalg.norm,1,a)
array([ 1.23244853,  2.62299312,  0.75780647,  2.67919815])
>>> c = divide_along_axis(a,np.apply_along_axis(np.linalg.norm,1,a),0)
>>> np.apply_along_axis(np.linalg.norm,1,c)
array([ 1.,  1.,  1.,  1.])

Answer

FredL picture FredL · Aug 22, 2011

For the specific example you've given: dividing an (l,m,n) array by (m,) you can use np.newaxis:

a = np.arange(1,61, dtype=float).reshape((3,4,5)) # Create a 3d array 
a.shape                                           # (3,4,5)

b = np.array([1.0, 2.0, 3.0, 4.0])                # Create a 1-d array
b.shape                                           # (4,)

a / b                                             # Gives a ValueError

a / b[:, np.newaxis]                              # The result you want 

You can read all about the broadcasting rules here. You can also use newaxis more than once if required. (e.g. to divide a shape (3,4,5,6) array by a shape (3,5) array).

From my understanding of the docs, using newaxis + broadcasting avoids also any unecessary array copying.

Indexing, newaxis etc are described more fully here now. (Documentation reorganised since this answer first posted).