This below should work and convert all NANs to 0
d[np.isnan(d)] = 0
If you want it all on one line, consider
d = np.nan_to_num(a1/a2)
Which will convert all NANs to 0, see here: http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.nan_to_num.html
Note: When dividing by 0, you should follow @imp9's solution below to avoid unnecessary warnings or errors.
Answer from Geotob on Stack OverflowThis below should work and convert all NANs to 0
d[np.isnan(d)] = 0
If you want it all on one line, consider
d = np.nan_to_num(a1/a2)
Which will convert all NANs to 0, see here: http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.nan_to_num.html
Note: When dividing by 0, you should follow @imp9's solution below to avoid unnecessary warnings or errors.
You should probably do the division in the context of np.errstate(divide='ignore', invalid='ignore') so that division by 0 doesn't raise an error or warnings, whether the dividend itself is zero or not (the two are separate warnings).
with np.errstate(divide='ignore', invalid='ignore'):
d = a1/a2
#Geotob's solution
d[np.isnan(d)] = 0
If you want it to raise warnings the change 'ignore' to 'warn'. Reference
Dividing nan by 0
BUG (Possible): masked array divide by zero array seems to screen out nan and inf
python - How to return 0 with divide by zero - Stack Overflow
python - convert nan value to zero - Stack Overflow
The easiest way to get this behaviour is to use numpy.float64 instead of Python default float type:
>>> import numpy
>>> numpy.float64(1.0) / 0.0
inf
Of course this requires NumPy. You can use numpy.seterr() to fine-tune the error handling.
Method 1:
try:
value = a/b
except ZeroDivisionError:
value = float('Inf')
Method 2:
if b != 0:
value = a / b
else:
value = float('Inf')
But be aware that the value could as well be -Inf, so you should make a more distinctive test. Nevertheless, this above should give you the idea how to do it.
So I've been working with np.nan and came across division by 0. Why doesn't np.nan "prevail" over the division by 0 (since it's not a number)? I tried np.nan*np.inf which is equal to np.nan. Why does this work and zero division doesn't?
In numpy v1.7+, you can take advantage of the "where" option for ufuncs. You can do things in one line and you don't have to deal with the errstate context manager.
>>> a = np.array([-1, 0, 1, 2, 3], dtype=float)
>>> b = np.array([ 0, 0, 0, 2, 2], dtype=float)
# If you don't pass `out` the indices where (b == 0) will be uninitialized!
>>> c = np.divide(a, b, out=np.zeros_like(a), where=b!=0)
>>> print(c)
[ 0. 0. 0. 1. 1.5]
In this case, it does the divide calculation anywhere 'where' b does not equal zero. When b does equal zero, then it remains unchanged from whatever value you originally gave it in the 'out' argument.
Building on @Franck Dernoncourt's answer, fixing -1 / 0 and my bug on scalars:
def div0( a, b, fill=np.nan ):
""" a / b, divide by 0 -> `fill`
div0( [-1, 0, 1], 0, fill=np.nan) -> [nan nan nan]
div0( 1, 0, fill=np.inf ) -> inf
"""
with np.errstate(divide='ignore', invalid='ignore'):
c = np.true_divide( a, b )
if np.isscalar( c ):
return c if np.isfinite( c ) \
else fill
else:
c[ ~ np.isfinite( c )] = fill
return c
Where A is your 2D array:
import numpy as np
A[np.isnan(A)] = 0
The function isnan produces a bool array indicating where the NaN values are. A boolean array can by used to index an array of the same shape. Think of it like a mask.
This should work:
from numpy import *
a = array([[1, 2, 3], [0, 3, NaN]])
where_are_NaNs = isnan(a)
a[where_are_NaNs] = 0
In the above case where_are_NaNs is:
In [12]: where_are_NaNs
Out[12]:
array([[False, False, False],
[False, False, True]], dtype=bool)
A complement about efficiency. The examples below were run with numpy 1.21.2
>>> aa = np.random.random(1_000_000)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit a[np.isnan(a)] = 0
536 µs ± 8.11 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.where(np.isnan(a), 0, a)
2.38 ms ± 27.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.nan_to_num(a, copy=True)
8.11 ms ± 401 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> a = np.where(aa < 0.15, np.nan, aa)
>>> %timeit np.nan_to_num(a, copy=False)
3.8 ms ± 70.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In consequence a[np.isnan(a)] = 0 is faster.