RuntimeWarning: Divide by Zero error: How to avoid? PYTHON, NUMPY

前端 未结 5 1528
遇见更好的自我
遇见更好的自我 2020-12-10 08:10

I am running in to RuntimeWarning: Invalid value encountered in divide

 import numpy
 a = numpy.random.rand((1000000, 100))
 b = numpy.random.rand((1,100))
          


        
相关标签:
5条回答
  • 2020-12-10 08:18

    You want to be using np.where. See the documentation.

    angles = np.where(norms != 0, dots/norms, -2)
    

    Angles will consist of downs/norms whenever norms != 0, and will be -2 otherwise. You will still get the RuntimeWarning, as np.where will still calculate the entire vector dots/norms internally, but you can safely ignore it.

    0 讨论(0)
  • 2020-12-10 08:21

    You could use angles[~np.isfinite(angles)] = ... to replace nan values with some other value.

    For example:

    In [103]: angles = dots/norms
    
    In [104]: angles
    Out[104]: array([[ nan,  nan,  nan, ...,  nan,  nan,  nan]])
    
    In [105]: angles[~np.isfinite(angles)] = -2
    
    In [106]: angles
    Out[106]: array([[-2., -2., -2., ..., -2., -2., -2.]])
    

    Note that division by zero may result in infs, rather than nans,

    In [140]: np.array([1, 2, 3, 4, 0])/np.array([1, 2, 0, -0., 0])
    Out[140]: array([  1.,   1.,  inf, -inf,  nan])
    

    so it is better to call np.isfinite rather than np.isnan to identify the places where there was division by zero.

    In [141]: np.isfinite(np.array([1, 2, 3, 4, 0])/np.array([1, 2, 0, -0., 0]))
    Out[141]: array([ True,  True, False, False, False], dtype=bool)
    

    Note that if you only want the top ten values from an NumPy array, using the np.argpartition function may be quicker than fully sorting the entire array, especially for large arrays:

    In [110]: N = 3
    
    In [111]: x = np.array([50, 40, 30, 20, 10, 0, 100, 90, 80, 70, 60])
    
    In [112]: idx = np.argpartition(-x, N)
    
    In [113]: idx
    Out[113]: array([ 6,  7,  8,  9, 10,  0,  1,  4,  3,  2,  5])
    
    In [114]: x[idx[:N]]
    Out[114]: array([100,  90,  80])
    

    This shows np.argpartition is quicker for even only moderately large arrays:

    In [123]: x = np.array([50, 40, 30, 20, 10, 0, 100, 90, 80, 70, 60]*1000)
    
    In [124]: %timeit np.sort(x)[-N:]
    1000 loops, best of 3: 233 µs per loop
    
    In [125]: %timeit idx = np.argpartition(-x, N); x[idx[:N]]
    10000 loops, best of 3: 53.3 µs per loop
    
    0 讨论(0)
  • 2020-12-10 08:28

    In newer versions of numpy there is a third alternative option that avoids needing to use the errstate context manager.

    All Numpy ufuncs accept an optional "where" argument. This acts slightly differently than the np.where function, in that it only evaluates the function "where" the mask is true. When the mask is False, it doesn't change the value, so using the "out" argument allows us to preallocate any default we want.

    import numpy as np
    
    angle = np.arange(-5., 5.)
    norm = np.arange(10.)
    
    # version 1
    with np.errstate(divide='ignore'):
        res1 = np.where(norm != 0., angle / norm, -2)
    
    # version 2
    with np.errstate(divide='ignore'):
        res2 = angle/norm
    res2[np.isinf(res2)] = -2
    
    # version 3
    res3 = -2. * np.ones(angle.shape)
    np.divide(angle, norm, out=res3, where=norm != 0)
    
    print(res1)
    print(res2)
    print(res3)
    
    np.testing.assert_array_almost_equal(res1, res2)
    np.testing.assert_array_almost_equal(res1, res3)
    
    0 讨论(0)
  • 2020-12-10 08:29

    you can ignore warings with the np.errstate context manager and later replace nans with what you want:

    import numpy as np
    angle = np.arange(-5., 5.) 
    norm = np.arange(10.)
    with np.errstate(divide='ignore'):
        print np.where(norm != 0., angle / norm, -2)
    # or:
    with np.errstate(divide='ignore'):
        res = angle/norm
    res[np.isnan(res)] = -2
    
    0 讨论(0)
  • 2020-12-10 08:31

    You can use np.where( condition ) to perform a conditional slice of where norms does not equal 0 before dividing:

    norms = np.where(norms != 0 ) 
    angles = dots/norms
    
    0 讨论(0)
提交回复
热议问题