我必须在 Python 中为我正在做的项目制作拉格朗日多项式。我正在做一种重心风格,以避免使用显式的 for 循环,而不是使用牛顿的分差风格。我遇到的问题是我需要将除以零,但 Python(或者可能是 numpy)只是将其作为警告而不是正常异常。
所以,我需要知道如何做的是捕捉这个警告,就好像它是一个异常一样。我在这个网站上找到的与此相关的问题没有以我需要的方式得到回答。这是我的代码:
import numpy as np import matplotlib.pyplot as plt import warnings class Lagrange: def __init__(self, xPts, yPts): self.xPts = np.array(xPts) self.yPts = np.array(yPts) self.degree = len(xPts)-1 self.weights = np.array([np.product([x_j - x_i for x_j in xPts if x_j != x_i]) for x_i in xPts]) def __call__(self, x): warnings.filterwarnings("error") try: bigNumerator = np.product(x - self.xPts) numerators = np.array([bigNumerator/(x - x_j) for x_j in self.xPts]) return sum(numerators/self.weights*self.yPts) except Exception, e: # Catch division by 0. Only possible in 'numerators' array return yPts[np.where(xPts == x)[0][0]] L = Lagrange([-1,0,1],[1,0,1]) # Creates quadratic poly L(x) = x^2 L(1) # This should catch an error, then return 1.
执行此代码时,我得到的输出是:
Warning: divide by zero encountered in int_scalars
这就是我想要捕捉的警告。它应该出现在列表理解中。
您的配置似乎正在使用以下print选项numpy.seterr:
print
numpy.seterr
>>> import numpy as np >>> np.array([1])/0 #'warn' mode __main__:1: RuntimeWarning: divide by zero encountered in divide array([0]) >>> np.seterr(all='print') {'over': 'warn', 'divide': 'warn', 'invalid': 'warn', 'under': 'ignore'} >>> np.array([1])/0 #'print' mode Warning: divide by zero encountered in divide array([0])
这意味着您看到的警告 不是 真正的警告,而只是打印到的一些字符stdout(请参阅文档seterr)。如果你想抓住它,你可以:
stdout
seterr
numpy.seterr(all='raise')
numpy.seterr(all='warn')
一旦你真正有一个警告,你可以使用该warnings模块来控制应该如何处理警告:
warnings
>>> import warnings >>> >>> warnings.filterwarnings('error') >>> >>> try: ... warnings.warn(Warning()) ... except Warning: ... print 'Warning was raised as an exception!' ... Warning was raised as an exception!
仔细阅读文档,filterwarnings因为它允许您仅过滤您想要的警告并具有其他选项。我还会考虑查看catch_warnings哪个是自动重置原始filterwarnings功能的上下文管理器:
filterwarnings
catch_warnings
>>> import warnings >>> with warnings.catch_warnings(): ... warnings.filterwarnings('error') ... try: ... warnings.warn(Warning()) ... except Warning: print 'Raised!' ... Raised! >>> try: ... warnings.warn(Warning()) ... except Warning: print 'Not raised!' ... __main__:2: Warning: