pythonnumpy

How to divide 2d matrix according to specified position


I have a feature map that needs to be divied with another 2d constant, the feature map has shape [H, W, ...] , the 2d constant has shape [H, W] , however when I use np.divide it says these two tensor can not be broadcast to a common shape:

import numpy as np

a = np.random.rand(4, 3 ,3)
b = np.random.rand(4, 3)

c = np.divide(a, b, where=b > 0)

as the numpy broadcast rules say b will be broadcast to shape [1, 4, 3] instead of [4, 3, 1] , thus I can't do this operation with boradcast.

I would like to divide my feature map with that constant tensor where the constant is not 0 to avoid zero-div error, what should I do ?


Solution

  • Personally, I would probably write:

    import numpy as np
    
    np.random.seed(3)  # Set seed for reproducibility
    a = np.random.rand(4, 3 ,3)
    b = np.random.normal(size=(4, 3))  # Use `normal` to produce more `where` misses
    
    b = b[..., np.newaxis]
    c = np.where(b > 0, a / b, a)
    

    However, to stay closer to your code, one could write equivalently:

    import numpy as np
    
    np.random.seed(3)  # Set seed for reproducibility
    a = np.random.rand(4, 3 ,3)
    b = np.random.normal(size=(4, 3))  # Use `normal` to produce more `where` misses
    
    c = a.copy()
    np.divide(a, b[..., np.newaxis], where=b[..., np.newaxis] > 0, out=c)
    

    Notable changes to your code:

    1. Manually add a dimension to b so that its shape is compatible with a (i.e. expand the 4×3 array to a 4×3×1 array).
    2. Provide an explicit output array out=c with np.divide(), because its where argument only produces meaningful results in connection with a given out array (see documentation of np.divide()).
    3. Use a copy of a as the output array, meaning that in places where b <= 0, the given a value will be the result instead (which is what you want, if I read your question correctly).

    In either case, the result will be contained in c.