python中除以0的处理方法

您所在的位置:网站首页 excel被零除错误 python中除以0的处理方法

python中除以0的处理方法

2023-07-16 00:17| 来源: 网络整理| 查看: 265

CSDN-blog-除以0问题 > 这篇blog用于记录如何在python里处理除以0的问题。 > 遇到的问题:在写矩阵运算,机器学习的过程中,会遇到矩阵相除的问题,之前的处理方法是在除法之前对每个元素逐个检查,但这样会导致无法利用numpy的并行计算的能力,最终导致计算速度大幅下降。

这个网站里提供里很好的讨论和指导https://www.codenong.com/26248654/

下面分别展示了三种处理除以0的方法,以个人愚见:

第一种方法比较普遍和通用(这个通用指换到其他语言或者脱离numpy,这个思路也感觉是可以的)第二种方法是最好的处理方法,对NaN和inF分别进行了处理第三种方法是最简洁的处理方法,只要一行,在对错误的情况理解比较清楚的时候,用这个也不错。 除以0会导致的两种错误 import numpy as np # 计算的被除数A,以及除数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

首先我们展示在除法计算的过程中,出现错误的类型主要可以分为两种0/0,以及1/0

对于0/0 的类型,得到的结果是Nan对于1/0 的类型,得到的结果是Inf(注意还有-inf) 思路一:分而治之

这个方法主要是提取了零元素和非零元素的位置,然后对非零元素进行计算,对零元素直接置约定的值。 但这个方法没有对两种除以0的错误类型分别进行操作,如果需要分开,则需要再进一步细分,分为三步:

对A和B都是非零元素操作对A是非零,B是零元素进行操作对A是零元素,B也是零元素进行操作 myOwnValue = 0 # 设置除数为0需要赋的值 arrayC = np.zeros(arrayA.shape) idxNonZeros = np.where(arrayB!=0) # 得到一个2x7的矩阵,分别对应了7个非零元素的位置 idxZeros = np.where(arrayB==0) # 得到一个2x2的矩阵,分别对应2个零元素的位置 # 除法按两步进行操作,首先是非零元素,随后计算零元素 # division in two steps: first with nonzero cells, and then zero cells arrayC[idxNonZeros] = arrayA[idxNonZeros] / arrayB[idxNonZeros] arrayC[idxZeros] = myOwnValue # 若约定为0是不需要这一步的,但如果约定不为0,例如为一极大值,则是必须的 print("*****************") print("arrayA / arrayB\n",arrayC) ***************** arrayA / arrayB [[0. 0.25 0. ] [0.6 0. 0.83333333] [0. 1. 4. ]] 思路二 先计算再解决(设计警告处理)

第一行的errstate是对浮点数错误的处理方式进行操作的上下文管理器

Context manager for floating-point error handling

顺手记录一下里面可以写的错误类型:

divide 除数为0的错误invalid 无效浮点数的错误over 浮点数溢出under 浮点数向下溢出(under-flow) with np.errstate(divide='ignore', invalid='ignore'): arrayC = arrayA / arrayB # 可以参考的对错误处理的方式 # arrayC[arrayC == np.inf] = 0 # 对inf的错误进行修正,不会修正-inf arrayC[~ np.isfinite(arrayC)] = 0 # 对 -inf, inf, NaN进行修正,置为0 # arrayC = np.nan_to_num(arrayC) # 对-inf, inf, NaN的错误进行修正了果置0,对inf置大数, # 但返回的为浮点数,不是True_division print("*****************") print("arrayA / arrayB\n",arrayC) ***************** arrayA / arrayB [[0. 0.25 0. ] [0.6 0. 0.83333333] [0. 1. 4. ]] 思路三 调用numpy的除法函数

事实上,numpy早就帮你考虑到除法问题了,所以提供了一个针对矩阵的除法函数,numpy.divide() 但这个方法依然只能统一处理两种除法为0错误,无法识别inf的问题,但是最简洁。

若输出处out,不指定dtype类型为浮点数,会出现错误(把浮点数赋给整数,精度丢失) 这里如果不指定out也会出现一样的结果,但不确定函数内部是不是默认初始值为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. ]]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3