Search code examples
pythonnumpyarray-broadcasting

Selectively set values in numpy array (or set on condition)


a = np.array([[0, 2, 0, 0], [0, 1, 3, 0], [0, 0, 10, 11], [0, 0, 1, 7]])
array([[ 0,  2,  0,  0],
       [ 0,  1,  3,  0],
       [ 0,  0, 10, 11],
       [ 0,  0,  1,  7]])

There are 0 entries in each row. I need to assign a value to each of these zero entries, where the value is calculated as follows:

V = 0.1 * Si / Ni

where Si is the sum of row i
      Ni is the number of zero entries in row i

I can calculate Si and Ni fairly easy:

S = np.sum(a, axis=1)
array([ 2,  4, 21,  8])

N = np.count_nonzero(a == 0, axis=1)
array([3, 2, 2, 2])

Now, V is calculated as:

V = 0.1 * S/N
array([0.06666667, 0.2       , 1.05      , 0.4       ])

But how do I assign V[i] to a zero entry in i-th row? So I'm expecting to get the following array a:

array([[ 0.06666667,  2,  0.06666667,  0.06666667],
       [ 0.2,  1,  3,  0.2],
       [ 1.05,  1.05, 10, 11],
       [ 0.4,  0.4,  1,  7]])

I need some kind of selective broadcasting operation or assignment?


Solution

  • Use np.where

    np.where(a == 0, v.reshape(-1, 1), a)

    array([[ 0.06666667,  2.        ,  0.06666667,  0.06666667],
           [ 0.2       ,  1.        ,  3.        ,  0.2       ],
           [ 1.05      ,  1.05      , 10.        , 11.        ],
           [ 0.4       ,  0.4       ,  1.        ,  7.        ]])