This website provides good discussion and guidance https://www.codenong.com/26248654/
Here are three ways to divide by 0, in my humble opinion:
- The first method is more common and general (this general refers to changing to other languages or breaking away from numpy. This idea also feels OK)
- The second method is the best treatment method. NaN and inF are treated respectively
- The third method is the most concise processing method. It's good to use it when you have a clear understanding of the wrong situation.
There are two kinds of errors caused by dividing by 0
import numpy as np
# Calculated divisor A, and divisor B arrayA = np.arange(9).reshape(3,3) arrayA[0,2]=0 arrayA[2,0]=-2 arrayB = np.array([[1,4,0], [5,0,6], [0,7,2]]) arrayC = arrayA / arrayB print("arrayA:\n", arrayA) print("arrayB:\n", arrayB) print("*****************") print("arrayA / arrayB\n",arrayC)
arrayA: [[ 0 1 0] [ 3 4 5] [-2 7 8]] arrayB: [[1 4 0] [5 0 6] [0 7 2]] ***************** arrayA / arrayB [[0. 0.25 nan] [0.6 inf 0.83333333] [ -inf 1. 4. ]] D:\Anaconda\lib\site-packages\ipykernel_launcher.py:8: RuntimeWarning: divide by zero encountered in true_divide D:\Anaconda\lib\site-packages\ipykernel_launcher.py:8: RuntimeWarning: invalid value encountered in true_divide
First, we show that there are two types of errors in the division calculation: 0 / 0 and 1 / 0
- For the type of 0 / 0, the result is Nan
- For 1 / 0 type, the result is inf (note - inf)
Idea 1: divide and rule
This method mainly extracts the position of zero element and non-zero element, then calculates the non-zero element, and directly sets the agreed value to the zero element.
However, this method does not operate the two error types divided by 0 separately. If they need to be separated, they need to be further subdivided into three steps:
- Non zero element operation for both A and B
- Operate on elements where A is non-zero and B is zero
- Operate on the fact that A is A zero element and B is also A zero element
myOwnValue = 0 # Set the divisor to 0 and assign a value to it arrayC = np.zeros(arrayA.shape) idxNonZeros = np.where(arrayB!=0) # A 2x7 matrix is obtained, which corresponds to the positions of 7 non-zero elements respectively idxZeros = np.where(arrayB==0) # Get a 2x2 matrix corresponding to the positions of two zero elements respectively # Division operates in two steps, first with non-zero elements and then with zero elements # division in two steps: first with nonzero cells, and then zero cells arrayC[idxNonZeros] = arrayA[idxNonZeros] / arrayB[idxNonZeros] arrayC[idxZeros] = myOwnValue # If the Convention is 0, this step is unnecessary, but if the Convention is not 0, such as a maximum value, it is necessary print("*****************") print("arrayA / arrayB\n",arrayC)
***************** arrayA / arrayB [[0. 0.25 0. ] [0.6 0. 0.83333333] [0. 1. 4. ]]
Train of thought 2: first calculate and then solve (design warning processing)
The errstate in the first line is the context manager that operates on the handling of floating-point errors
Context manager for floating-point error handling
Conveniently record the error types that can be written in it:
- Division error of divide 0
- Invalid invalid floating point number error
- over floating point overflow
- Under floating point number down overflow (under flow)
with np.errstate(divide='ignore', invalid='ignore'): arrayC = arrayA / arrayB # Refer to the error handling methods # arrayC[arrayC == np.inf] = 0 # The error of inf will be corrected, and - inf will not be corrected arrayC[~ np.isfinite(arrayC)] = 0 # Correct - inf, inf, NaN and set it to 0 # arrayC = np.nan_to_num(arrayC) # The errors of - inf, inf and Nan are corrected. The result is set to 0 and inf is set to a large number, # But the returned is a floating-point number, not True_division print("*****************") print("arrayA / arrayB\n",arrayC)
***************** arrayA / arrayB [[0. 0.25 0. ] [0.6 0. 0.83333333] [0. 1. 4. ]]
Idea 3: call the division function of numpy
In fact, numpy has already helped you consider the division problem, so it provides a matrix division function, numpy divide()
However, this method can only deal with the problem that the two division errors are 0 and inf cannot be recognized, but it is the most concise.
If the output is out and the dtype type is not specified as a floating-point number, an error will occur (assigning a floating-point number to an integer will lose precision)
If out is not specified here, the same result will appear, but it is uncertain whether the default initial value inside the function is 0
arrayC = np.divide(arrayA, arrayB, out=np.zeros_like(arrayA, dtype=np.float64), where=arrayB!=0) print("*****************") print("arrayA / arrayB\n",arrayC)
***************** arrayA / arrayB [[0. 0.25 0. ] [0.6 0. 0.83333333] [0. 1. 4. ]]