如何区分两个numpy FloatingPointError异常?

时间:2015-07-01 15:19:38

标签: python exception numpy

我对python中的异常并不熟悉,所以我试图在这里解决问题。 numpy中有两个不同的FloatingPointError例外:

import numpy as np
import sys
np.seterr(divide='raise', invalid='raise')
try:
    np.float64(0.0) / np.float64(0.0)
except FloatingPointError:
    tb = sys.exc_info()

print(tb)

(<type 'exceptions.FloatingPointError'>,
FloatingPointError('invalid value encountered in double_scalars',),
traceback object at 0x10bd50cb0>)


try:
    np.float64(1.0) / np.float64(0.0)
except FloatingPointError:
    tb = sys.exc_info()

print(tb)

(<type 'exceptions.FloatingPointError'>,
FloatingPointError('divide by zero encountered in double_scalars',),
traceback object at 0x10faede60>)

我需要在我的程序中将0/0操作定义为0,这样我应该在第一个和第二个异常之间有所不同。以下是我对问题的解决方案:

if str(tb[1]) == 'invalid value encountered in double_scalars':
    print('first exception found')
else:
    print('second exception found')

但我想我可以通过比较错误代码或类似的东西来做到这一点。那我怎么能在python中做到呢?

2 个答案:

答案 0 :(得分:3)

最好通过error callback function

设置numpy.seterr()
class InvalidValueError(Exception): pass
class DivideByZeroError(Exception): pass

def err_handler(err, flag):
    if flag == 8:
        raise InvalidValueError(err)
    if flag == 1:
        raise DivideByZeroError(err)

np.seterrcall(err_handler)
np.seterr(divide='call', invalid='call')

在这种情况下,您可以根据错误类型TODO进行操作。

try:
    np.float64(0.0) / np.float64(0.0)
    # or `np.float64(1.0) / np.float64(0.0)`
except InvalidValueError:
    # TODO
except DivideByZeroError:
    # TODO

答案 1 :(得分:2)

这应该由IEEE浮点异常处理,其中0.0/0.0 = NaN1.0/0.0 = inf

在您的示例中,您可以忽略相应的numpy警告

np.seterr(divide='ignore', invalid='ignore')

计算除法的结果,然后用np.isnannp.isinf对其进行测试,以区分这两种情况并妥善处理它们,

def validate_division(a, b):
   a = np.float64(a)
   b = np.float64(b)
   res = a/b
   if np.isinf(res):
       print('Dividing by zero')
   elif np.isnan(res):
       print('Both numbers are zero')
   else:
       print('The division is valid')

忽略两个数组0.0/0.0a之间的numpy操作中的b分区的典型方法是,

res = a/b
mask = np.isinf(res)
res[mask] = 0 # set the NaN elements to 0.0