'Replacing each non-zero element with the inverse of it in Python

I would like to replace each non-zero element of R4_mod with the inverse of it. The desired output is attached.

import numpy as np

R4_mod=np.array([[0.00000000e+00, 1.96129124e+10, 0.00000000e+00, 1.88618492e+10,
        0.00000000e+00],
       [6.94076420e+09, 0.00000000e+00, 1.11642674e+09, 0.00000000e+00,
        1.73640817e+10],
       [0.00000000e+00, 1.96129124e+10, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00],
       [6.94076420e+09, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        1.73640817e+10],
       [0.00000000e+00, 1.96129124e+10, 0.00000000e+00, 1.88618492e+10,
        0.00000000e+00]]) 

The desired output is

array([[0.00000000e+00, 1/1.96129124e+10, 0.00000000e+00, 1/1.88618492e+10,
        0.00000000e+00],
       [1/6.94076420e+09, 0.00000000e+00, 1/1.11642674e+09, 1/0.00000000e+00,
        1.73640817e+10],
       [0.00000000e+00, 1/1.96129124e+10, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00],
       [1/6.94076420e+09, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        1/1.73640817e+10],
       [0.00000000e+00, 1/1.96129124e+10, 0.00000000e+00, 1/1.88618492e+10,
        0.00000000e+00]])


Solution 1:[1]

We can create a Boolean masked array that shows where the array contains non_zero values as:

mask = R4_mod != 0

# [[False  True False  True False]
#  [ True False  True False  True]
#  [False  True False False False]
#  [ True False False False  True]
#  [False  True False  True False]]

Then we can do the operation just on the True values of the mask:

Trues = R4_mod[mask]

# [1.96129124e+10 1.88618492e+10 6.94076420e+09 
#  1.11642674e+09 1.73640817e+10 1.96129124e+10 
#  6.94076420e+09 1.73640817e+10 1.96129124e+10
#  1.88618492e+10]

masked_work = 1 / Trues 

# [5.0986818255508041e-11 5.3017071093962513e-11 1.4407635401300624e-10 
#  8.9571484108307902e-10 5.7590145985088284e-11 5.0986818255508041e-11
#  1.4407635401300624e-10 5.7590145985088284e-11 5.0986818255508041e-11
#  5.3017071093962513e-11]

Now, by applying the calculated values on the main array using masked array we get the result:

R4_mod[mask] = masked_work

All of this steps can be done in one line as:

R4_mod[R4_mod != 0] = 1 / R4_mod[R4_mod != 0]

It must be noted that this solution will changes the original array to the resulted one. If you need the original array, you must do these steps on a copy of the main array.

Solution 2:[2]

As mentioned in the comments, np.divide can help you if you specify the where parameter. Like so:

np.divide(1, R4_mod, where=R4_mod!=0, out=R4_mod)

After this, R4_mod will contain the result of the divisions. As far as time and space complexity, this approach should be preferable to

R4_mod[R4_mod != 0] = 1 / R4_mod[R4_mod != 0]

which works but creates an in-memory bit array (R4_mod != 0) twice and doesn't fully exploit numpy.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ali_Sh
Solution 2