[PYTHON] 예외 (테스트 만)가 아닌 것처럼 numpy 경고를 어떻게 catch합니까?
PYTHON예외 (테스트 만)가 아닌 것처럼 numpy 경고를 어떻게 catch합니까?
내가하고있는 프로젝트를 위해 Python에서 Lagrange 다항식을 만들어야합니다. 저는 뉴턴의 분할 된 차이 스타일과는 달리 명시적인 for-loop를 사용하지 않으려 고하는 중력 스타일을하고 있습니다. 내가 가진 문제는 0으로 나눗셈을 잡아야한다는 것이지만, 파이썬 (또는 아마 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
그것이 내가 잡으려고하는 경고입니다. 그것은 목록 이해력 내에서 발생해야합니다.
해결법
-
==============================
1.귀하의 구성이 numpy.seterr에 대한 인쇄 옵션을 사용하고있는 것 같습니다 :
귀하의 구성이 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 설명서 참조). 그것을 잡으려면 다음을 할 수 있습니다.
실제로 경고가 발생하면 경고 모듈을 사용하여 경고를 처리하는 방법을 제어 할 수 있습니다.
>>> 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에 대한 설명서를주의 깊게 읽으십시오. 원하는 경고 만 필터링하고 다른 옵션을 사용할 수 있기 때문입니다. 또한 원래 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:
-
==============================
2.@ Bakuriu의 답변에 약간을 추가하려면 다음을 수행하십시오.
@ Bakuriu의 답변에 약간을 추가하려면 다음을 수행하십시오.
이미 어디에서 경고가 발생하는지 알고 있다면 numpy.errstate 컨텍스트 관리자를 사용하는 것이 더 깨끗합니다. numpy.seterr는 코드 내에서 발생하는 위치에 관계없이 동일한 유형의 모든 후속 경고를 동일하게 처리합니다.
import numpy as np a = np.r_[0] with np.errstate(divide='raise'): try: a / 0 # this gets caught and handled as an exception except FloatingPointError: print('oh no!') a / 0 # this prints a RuntimeWarning as usual
-
==============================
3.위의 @ Bakuriu의 대답에 대해 자세히 설명하기 위해이 방법을 사용하면 오류 경고를 잡아 내고 멋지게 경고를 출력하는 것과 비슷한 방식으로 런타임 경고를 잡을 수 있습니다.
위의 @ Bakuriu의 대답에 대해 자세히 설명하기 위해이 방법을 사용하면 오류 경고를 잡아 내고 멋지게 경고를 출력하는 것과 비슷한 방식으로 런타임 경고를 잡을 수 있습니다.
import warnings with warnings.catch_warnings(): warnings.filterwarnings('error') try: answer = 1 / 0 except Warning as e: print('error found:', e)
이런 식으로 잡기 오류로 캐스팅하려는 우산의 크기에 따라 warnings.catch_warnings () 배치를 배치하는 것으로 놀 수도 있습니다.
-
==============================
4.warnings.filterwarnings을 삭제하고 다음을 추가하십시오.
warnings.filterwarnings을 삭제하고 다음을 추가하십시오.
numpy.seterr(all='raise')
from https://stackoverflow.com/questions/15933741/how-do-i-catch-a-numpy-warning-like-its-an-exception-not-just-for-testing by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] TypeError : 'NoneType'객체는 파이썬에서 반복 가능하지 않습니다. (0) | 2018.10.07 |
---|---|
[PYTHON] 목록에서 최대 값의 모든 위치를 찾는 방법? (0) | 2018.10.07 |
[PYTHON] 셀레늄 요소 보이지 않는 예외 (0) | 2018.10.07 |
[PYTHON] Python : Base64 디코딩시 '잘못된 패딩'오류 무시 (0) | 2018.10.07 |
[PYTHON] Flask 요청의 다른 부분을 어떻게 얻습니까? (0) | 2018.10.07 |