티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
How do I catch a numpy warning like it's an exception (not just for testing)?
exception처럼 numpy 경고 받기
문제 내용
I have to make a Lagrange polynomial in Python for a project I'm doing. I'm doing a barycentric style one to avoid using an explicit for-loop as opposed to a Newton's divided difference style one. The problem I have is that I need to catch a division by zero, but Python (or maybe numpy) just makes it a warning instead of a normal exception.
나는 내가 하고 있는 프로젝트를 위해 파이썬에서 라그랑주 다항식을 만들어야 한다. 나는 뉴턴의 분할된 차이 스타일과 반대로 명시적인 for-loop을 사용하는 것을 피하기 위해 barycentric 스타일을 하고 있다. 문제는 0으로 나눗셈을 잡아야 하는데 파이썬(또는 numpy)이 일반적인 예외 대신 경고로 만든다는 것이다.
So, what I need to know how to do is to catch this warning as if it were an exception. The related questions to this I found on this site were answered not in the way I needed. Here's my code:
그래서 내가 알아야 할 것은 이 경고를 예외인 것처럼 잡는 것이다. 내가 이 사이트에서 찾은 이것과 관련된 질문들은 내가 필요로 하는 방식으로 대답되지 않았다. 제 코드는 이렇습니다.
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.
When this code is executed, the output I get is:
이 코드가 실행되면 출력은 다음과 같습니다.
Warning: divide by zero encountered in int_scalars
That's the warning I want to catch. It should occur inside the list comprehension.
그것이 내가 듣고 싶은 경고이다. 그것은 목록 이해 안에서 발생해야 한다.
높은 점수를 받은 Solution
It seems that your configuration is using the print
option for numpy.seterr
:
구성에서 numpy.seterr에 대한 print 옵션을 사용하는 것 같습니다:
>>> 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])
This means that the warning you see is not a real warning, but it's just some characters printed to stdout
(see the documentation for seterr
). If you want to catch it you can:
즉, 표시되는 경고는 실제 경고가 아니라 stdout에 인쇄된 일부 문자일 뿐입니다(seterr에 대한 설명서 참조). 당신이 그것을 잡고 싶다면 당신은(는)
- Use
numpy.seterr(all='raise')
which will directly raise the exception. This however changes the behaviour of all the operations, so it's a pretty big change in behaviour. - Use
numpy.seterr(all='warn')
, which will transform the printed warning in a real warning and you'll be able to use the above solution to localize this change in behaviour.
1. 예외를 직접 발생시키는 numpy.seterr(all='raise')입니다. 그러나 이것은 모든 작업의 동작을 변경하므로 동작에 꽤 큰 변화가 있습니다.
2. numpy.seterr(all='warn') - 실제 경고에서 인쇄된 경고를 변환하고 위의 솔루션을 사용하여 이러한 동작 변화를 현지화할 수 있습니다.
Once you actually have a warning, you can use the warnings
module to control how the warnings should be treated:
경고가 실제로 발생하면 경고 모듈을 사용하여 경고를 처리하는 방법을 제어할 수 있습니다.
>>> import warnings
>>>
>>> warnings.filterwarnings('error')
>>>
>>> try:
... warnings.warn(Warning())
... except Warning:
... print 'Warning was raised as an exception!'
...
Warning was raised as an exception!
Read carefully the documentation for filterwarnings
since it allows you to filter only the warning you want and has other options. I'd also consider looking at catch_warnings
which is a context manager which automatically resets the original filterwarnings
function:
필터 경고는 원하는 경고만 필터링할 수 있고 다른 옵션도 있으므로 설명서를 주의 깊게 읽어 보십시오. 원래 필터 경고 기능을 자동으로 재설정하는 컨텍스트 관리자인 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:
가장 최근 달린 Solution
Remove warnings.filterwarnings and add:
warnings.filterwarnings를 제거하고, 추가합니다:
numpy.seterr(all='raise')
출처 : https://stackoverflow.com/questions/15933741/how-do-i-catch-a-numpy-warning-like-its-an-exception-not-just-for-testing
'개발 > 파이썬' 카테고리의 다른 글
파이썬에서 두 개의 리스트 연결하기 (0) | 2022.11.29 |
---|---|
리스트에서 아이템의 인덱스 찾기 (0) | 2022.11.29 |
Dictionary에 새 키를 추가하는 방법 (0) | 2022.11.29 |
리스트 안에 리스트가 있을 때 펼쳐서 일반 리스트로 만드는 방법 (0) | 2022.11.29 |
Dictionary를 value로 정렬하려면 어떻게 해야 합니까? (0) | 2022.11.29 |