(테스트뿐만 아니라) 예외인 것처럼 numpy 경고를 수신하려면 어떻게 해야 합니까?
내가 하고 있는 프로젝트를 위해 파이썬에서 라그랑주 다항식을 만들어야 한다.뉴턴의 분할 차분 스타일과 달리 명시적인 for-loop을 사용하지 않기 위해 중심 스타일을 사용하고 있습니다.문제는 0으로 나눗셈을 해야 하는데 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
옵션:
>>> 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
(의 메뉴얼을 참조해 주세요).잡으려면 다음 작업을 수행합니다.
- 사용하다
numpy.seterr(all='raise')
그러면 예외가 직접 발생합니다.그러나 이는 모든 작업의 동작을 변화시키므로 동작에 있어 상당히 큰 변화입니다. - 사용하다
numpy.seterr(all='warn')
그러면 실제 경고로 출력된 경고가 변환되고 위의 솔루션을 사용하여 동작의 변화를 현지화할 수 있습니다.
실제로 경고가 발생하면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
기능:
>>> 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:
@Bakuriu의 답변에 조금 덧붙이자면:
경고가 발생할 가능성이 있는 장소를 이미 알고 있는 경우, 대부분의 경우 컨텍스트 매니저를 사용하는 것이 좋습니다.이는 코드 내에서 발생하는 위치에 관계없이 동일한 유형의 모든 경고를 동일하게 취급하는 것이 아닙니다.
import numpy as np
a = np.r_[1.]
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
편집:
제 원래 예에서는a = np.r_[0]
그러나 분명히 numpy의 동작에 변화가 있어 분자가 모두 채워진 경우 0으로 나누면 다르게 처리된다.예를 들어 numpy 1.16.4의 경우:
all_zeros = np.array([0., 0.])
not_all_zeros = np.array([1., 0.])
with np.errstate(divide='raise'):
not_all_zeros / 0. # Raises FloatingPointError
with np.errstate(divide='raise'):
all_zeros / 0. # No exception raised
with np.errstate(invalid='raise'):
all_zeros / 0. # Raises FloatingPointError
.「알겠습니다.」1. / 0.
되어 있습니다.RuntimeWarning: divide by zero encountered in true_divide
에 , ,는.0. / 0.
되어 있습니다.RuntimeWarning: invalid value encountered in true_divide
수만, 이 변경의 가, 이 변경의 0. / 0.
수 합니다). numpy는 NaN을 반환합니다(numpy는 NaN을 반환합니다).1. / 0.
★★★★★★★★★★★★★★★★★」-1. / 0.
IEE 754 - Inf inf iinf i i i i 。
의 오류를 모두 때는 시킬 수 있습니다.np.errstate(divide='raise', invalid='raise')
, 「」all='raise'
부동소수점 오류에 대해 예외를 발생시키는 경우.
위의 @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() placement를 사용할 수 있습니다.
경고를 삭제합니다.필터 경고 및 추가:
numpy.seterr(all='raise')
언급URL : https://stackoverflow.com/questions/15933741/how-do-i-catch-a-numpy-warning-like-its-an-exception-not-just-for-testing
'it-source' 카테고리의 다른 글
Larabel 5.5 ajax 콜 419(알 수 없는 상태) (0) | 2022.12.29 |
---|---|
MySQL(MariaDB) 업데이트 트랜잭션에서 '영향을 받는 0행'이 반환되는 이유는 무엇입니까? (0) | 2022.12.29 |
'mysqldump'를 사용하여 CSV 형식의 모든 테이블 덤프 (0) | 2022.12.19 |
vue에서 sass 변수를 재정의하려면 어떻게 해야 합니까? (0) | 2022.12.19 |
엔티티 프레임워크 MariaDb 문자열 날짜 문제 (0) | 2022.12.19 |