I am using numpy "choose()" in order to work around dividing by zero, and for the most part my code seems to work. However, I still get the warning message:
RuntimeWarning: divide by zero encountered in true_divide ycmpnt = np.choose( np.abs(a)>0 , ( 0., (a 1) / a ))
Even though no issues appear to arise, this results in an unacceptable amount of text in my Console since the code loops hundred of times. Any ideas what is going on here?
a = np.array([[0., 1., 2., 3.], [10., 11., 0., 13.],
[20., 21., 22., 23.], [0., 31., 32., 33.]])
ycmpnt = np.choose( np.abs(a)>0 , ( 0., (a 1) / a ))
count = np.choose( np.abs(a)>0 , ( 0., 1))
CodePudding user response:
The Problem
Unfortunately, the popular NumPy function np.choose()
does not allow for conditional execution (neither does np.where()
, btw). Since the Python function parameters are evaluated in their entirety before the function call, they cannot be conditionally evaluated for a subset of its parameters. In turn, a RuntimeWarning
about the division of zero is provided although you tried to make sure this does not happen.
The Solution
I would replace np.choose()
with the NumPy function for element-wise division. np.divide()
allows the specification of a condition that must be met for division (namely that the element is non-zero a!=0
) through the where
argument. In turn, no runtime error is thrown. More generally, the where
argument can be provided to any NumPy function that operates element by element on a given array, so-called ufuncs. Where the condition is not met, the array a
will retain its original value, i.e. 0
in your case.
Additionaly, I'd leverage np.where()
to count (non-)zero entries.
a = np.array([[0., 1., 2., 3.], [10., 11., 0., 13.], [20., 21., 22., 23.], [0., 31., 32., 33.]])
ycmpnt = np.divide(a 1, a, out=np.zeros_like(a), where=a!=0)
count = np.where(a!=0, 0, 1)
Note that np.abs(a)>0
should be replaced with the algebraically equivalently but faster a!=0
.