Jan
Jan

Reputation: 1479

Mean each row of nonzero values and avoid RuntimeWarning and NaN as some rows are all zero

I already checked Numpy mean of nonzero values and it worked nicely. However, some rows of my matrix are all zero element. What is a good way to avoid RuntimeWarning: invalid value encountered in true_divide in this case? Also, I don't want the zero element to be replaced by Nan here.

eachPSM = np.ones([3,4])
eachPSM[0] = 0
print eachPSM
>> [[ 0.  0.  0.  0.]
 [ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]]
print np.true_divide(eachPSM.sum(1),(eachPSM!=0).sum(1))
>> RuntimeWarning: invalid value encountered in true_divide
[ nan   1.   1.]

Upvotes: 0

Views: 69

Answers (4)

Divakar
Divakar

Reputation: 221664

With a as the input array, you could use masking -

invalid_val = np.nan # specifies mean value to be assigned for all zeros rows
out = np.full(a.shape[0],invalid_val)
count = (a!=0).sum(1)
valid_mask = count!=0
out[valid_mask] = a[valid_mask].sum(1)/count[valid_mask]

Upvotes: 2

B. M.
B. M.

Reputation: 18668

Masked array provide elegant solutions :

eachPSM = np.ones([3,4])
eachPSM[0] = 0
eachPSM[1,1] = 0

#[[ 0.  0.  0.  0.]
# [ 1.  0.  1.  1.]
# [ 1.  1.  1.  1.]]

In [39]: np.ma.masked_equal(eachPSM,0).mean(1)
Out[39]: 
masked_array(data = [-- 1.0 1.0],
             mask = [ True False False],
       fill_value = 1e+20)

In [40]: np.ma.masked_equal(eachPSM,0).mean(1).data
Out[40]: array([ 0.,  1.,  1.])

Upvotes: 0

Bharath M Shetty
Bharath M Shetty

Reputation: 30605

Since anything divided by 1 is same as the numerator you can fill zero by 1 i.e

x = eachPSM.sum(1)
y = (eachPSM!=0).sum(1)
y[y==0] =  1 
np.true_divide(x,y)

#array([ 0.,  1.,  1.])

Upvotes: 0

Eric Bridger
Eric Bridger

Reputation: 3794

import warnings
...
with warnings.catch_warnings():
  warnings.simplefilter("ignore", category=RuntimeWarning)

eachPSM[np.isnan(eachPSM)] = 0

Upvotes: 0

Related Questions