0

I have a code snippet:

import numpy as np
x1 = [[1,4,2,1],       
      [1,1,4,5],
      [0.5,0.3, 1,6],
      [0.8,0.2,0.7,1]]

x2 = [[7,0,2,3],       
      [8,0,4,5],
      [0.1,0, 2,6],
      [0.1,0,0.16666667,6]]

np.true_divide(x1, x2)

The output is:

array([[0.14285714,        inf, 1.        , 0.33333333],
       [0.125     ,        inf, 1.        , 1.        ],
       [5.        ,        inf, 0.5       , 1.        ],
       [8.        ,        inf, 4.19999992, 0.16666667]])

I am aware that some elements will have zerodivision error which can be seen as 'inf'.

How can I use 'try and except' to change all these 'inf' results into 0? Or is there a better method to convert all those 'inf's into 0?

manacoder
  • 31
  • 8

2 Answers2

2

You can use numpy.where to select the values for which the division result or the original values be retained:

import numpy as np
x1 = np.array([[1,4,2,1],       
               [1,1,4,5],
               [0.5,0.3, 1,6],
               [0.8,0.2,0.7,1]])
x2 = np.array([[7,0,2,3],       
               [8,0,4,5],
               [0.1,0, 2,6],
               [0.1,0,0.16666667,6]])

np.where(x2==0, 0, x1/x2)
# or
# np.where(x2==0, x2, np.true_divide(x1, x2))

Output:

array([[0.14285714, 0.        , 1.        , 0.33333333],
       [0.125     , 0.        , 1.        , 1.        ],
       [5.        , 0.        , 0.5       , 1.        ],
       [8.        , 0.        , 4.19999992, 0.16666667]])

Alternatively, use the where parameter of numpy.divide to retain the original value:

np.divide(x1, x2, where=x2!=0)

Note that the behavior is less obvious and you might want to check that both values are non-null:

x1 = np.array([2,2,0,0])
x2 = np.array([2,0,2,0])
np.divide(x1, x2, where=(x2!=0)&(x1!=0)).round(10)
# array([1., 0., 0., 0.])
mozway
  • 194,879
  • 13
  • 39
  • 75
  • How does this work? Aren't the function arguments evaluated before calling `np.where()`? So the division by 0 will happen before `np.where()` can select the rows. – Barmar Apr 05 '23 at 23:54
  • @Barmar you'll get a warning, but this is not an issue. OP asked to have 0 where the division by 0 would happen, which this code it doing. Another option would be to use the `where` parameter of `np.divide`. I updated the answer. – mozway Apr 06 '23 at 08:00
  • Thanks. I ran into your answer while researching [this question](https://stackoverflow.com/questions/75944700/when-using-np-where-im-getting-runtimewarning-divide-by-zero-encountered-in-di) and didn't notice that their problem was just a warning, not an error. – Barmar Apr 06 '23 at 15:00
1

0/0 can handle by adding invalid='ignore' to numpy.errstate() introducing numpy.nan_to_num() to convert np.nan to 0.

with np.errstate(divide='ignore', invalid='ignore'):
    c = np.true_divide(x1,x2)
    c[c == np.inf] = 0
    c = np.nan_to_num(c)
print(c)

Output

[[0.14285714 0.         1.         0.33333333]
 [0.125      0.         1.         1.        ]
 [5.         0.         0.5        1.        ]
 [8.         0.         4.19999992 0.16666667]]
mhhabib
  • 2,975
  • 1
  • 15
  • 29