Numpyのwarningを例外処理にしてロギング
numpyのfloating-point errorはデフォルトではwarningを出す。
http://docs.scipy.org/doc/numpy/reference/generated/numpy.seterr.html
ここの情報によると、
http://stackoverflow.com/questions/10519237/python-how-to-avoid-numpy-runtimewarning-in-function-definition
numpy.errstateでRuntimeWarningをFloatingPointErrorにするのが、良さそうだ。
np.errstateの挙動はこんな感じ。
In [3]: with np.errstate(all='raise'): ...: np.array([1.0])/0 ...: --------------------------------------------------------------------------- FloatingPointError Traceback (most recent call last) <ipython-input-3-34478ac4bed1> in <module>() 1 with np.errstate(all='raise'): ----> 2 np.array([1.0])/0 3 FloatingPointError: divide by zero encountered in divide
例外として捉える。
#!/usr/bin/env python import numpy as np try: with np.errstate(all='raise'): np.array([1.0])/0 except FloatingPointError as exc: print exc
他に、WarningをErrorして捉える方法は例えばここら
http://stackoverflow.com/questions/15933741/how-do-i-catch-a-warning-in-python-like-its-an-exception-not-just-for-testing
に書いている。warnings.filterwarnings('error')を使う。
#!/usr/bin/env python import numpy as np import warnings warnings.filterwarnings('error') try: np.array([1.0]) / 0 except RuntimeWarning as exc: print exc
少し用途は違いそうだけど、warnings.catch_warnings(record=True)というのもある。
https://docs.python.org/2/library/warnings.html#testing-warnings
例外の内容はsys.exc_info()に記録される。
https://docs.python.org/2/library/sys.html
例外の捉え方
https://docs.python.org/2.7/tutorial/errors.html
sys.exc_info()の出力を文字列に変換する方法などがここに書いている。
http://melpystudio.blog82.fc2.com/blog-entry-87.html
traceback.format_exception()も便利なようだ。これは、logging.exception('')の文字列出力と同じのようだ。
http://stackoverflow.com/questions/4508849/how-to-log-python-exception
ロギングに関してはここが参考になる。
http://stackoverflow.com/questions/4508849/how-to-log-python-exception
https://docs.python.org/2/library/logging.html
まとめ
#!/usr/bin/env python import numpy as np import sys import traceback import warnings import logging logging.basicConfig(filename='test.log',level=logging.DEBUG) def test_filterwarnings(): warnings.filterwarnings('error') try: np.array([1.0]) / 0 except RuntimeWarning as exc: print exc def test_errstate(): try: with np.errstate(all='raise'): np.array([1.0])/0 except FloatingPointError as exc: print exc logging.exception('') # saved to test.log exc_type, exc_value, exc_traceback = sys.exc_info() print ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)) test_filterwarnings() test_errstate()
Numpyのinfとnan
logを使って、nanとinfを出す。
In [4]: np.log([-1.]) /opt/local/bin/ipython:1: RuntimeWarning: invalid value encountered in log #!/opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python Out[4]: array([ nan]) In [5]: np.log([-0.]) /opt/local/bin/ipython:1: RuntimeWarning: divide by zero encountered in log #!/opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python Out[5]: array([-inf])
np.errstateを使って例外にするとFloatingPointErrorになる。
In [3]: with np.errstate(all='raise'): np.log([-1]) ...: --------------------------------------------------------------------------- FloatingPointError Traceback (most recent call last) <ipython-input-3-23ac75103728> in <module>() 1 with np.errstate(all='raise'): ----> 2 np.log([-1]) 3 FloatingPointError: invalid value encountered in log In [4]: with np.errstate(all='raise'): ...: np.log([0]) ...: --------------------------------------------------------------------------- FloatingPointError Traceback (most recent call last) <ipython-input-4-c940e768b715> in <module>() 1 with np.errstate(all='raise'): ----> 2 np.log([0]) 3 FloatingPointError: divide by zero encountered in log