pythonの0除算の回避方法 発生の例外処理やNumpy

pythonの0除算

Pythonの0除算のZeroDivisionErrorを回避

Pythonの0除算のZeroDivisionErrorを回避

Pythonの0除算を回避

Pythonの0除算を回避

Pythonでは、0除算をおこなうと、エラーが起こった時点で処理が止まってしまいます。

一般の開発言語では「NaN」(Not a Number)というものが定義されていて、0除算でも止まらないものもあるんですね。PythonにもNaNはあるのに、エラーで止まるのはそのまま計算を進めて致命傷になるのを防ぐため…?

関連)PythonのNan判定の方法

以下の例だと、「処理終了」の表示を行わずに、x/yの演算が行われた時点でエラーを表示して処理が停止してしまいます。

$ cat zerodivide.py
#!/usr/bin/python3
x = 1
y = 0

print( x / y )
print( "処理終了" )

実際に実行するとこう。print( “処理終了” )が実行されていません。

$ ./zerodivide.py
Traceback (most recent call last):
File "./zerodivide.py", line 5, in <module>
print( x / y )
ZeroDivisionError: division by zero

すごくまっとうなエラー回避対応としては、0除算が起こらないよう演算前の変数の内容をチェックするという方法があります。x/yという演算を行うなら、yが0だったらx/yという演算を行わないか、y=0にならないようにif文で記述します。

関連 Pythonのif文

例えば、y=0だったら、y=1に変更する場合は、x/yの処理の前に以下を記述します。

if( y == 0 ):
y = 1

それ以外に、「とにかくエラーが起きたら別の処理を実行したいんだ」ってときは、例外処理を使います。

Pythonの0除算の例外処理

Pythonの0除算の例外処理

x/yを実行する際に、try~exceptで例外処理を記述すれば、エラーが表示されず、処理も止まりません。

$ cat zerodivide_except.py
#!/usr/bin/python3
x = 1
y = 0

try:
print( x / y )
except:
print( "例外が発生" )

print( "処理終了" )

実行するとこうなります。

$ ./zerodivide_except.py
例外が発生
処理終了

ケースバイケースですが、コードの書き方としては、かなりすっきりしますね。

Pythonのnumpyの0除算

Pythonのnumpyの0除算

データ型として、numpyを使うと、処理は止まりません。ただし、警告は表示されます。

$ cat ./zerodivide_numpy.py
#!/usr/bin/python3
import numpy as np

x = np.array([1])
y = np.array([0])

print( x / y )
print( "処理終了" )

import時にnumpyをnpとしてインポートするのは、昔からある習わしのようなものです。

関連 python importの使い方

実行するとこうなります。

$ ./zerodivide_numpy.py
./zerodivide_numpy.py:7: RuntimeWarning: divide by zero encountered in true_divide
print( x / y )
[ inf]
処理終了

print( “処理終了” )が実行されていて、処理が止まらず最後まで実行されたのが確認できます。

となると、次はこの警告を回避したくなりますね。ちなみに、numpyのRuntimeWarningは、try~Exceptで補足できません。

警告表示をなくすには、numpy.errstate(divide=’ignore’)を実行します。すると、以降はdivide by zero encounteredの警告が無視されて表示されなくなります。

全体で無視されると困る…という場合は、with句で使用すると、警告を無視する箇所をwith内に限定することができます。

$ cat ./zerodivide_numpy_nowarning.py
#!/usr/bin/python3
import numpy as np

x = np.array([1])
y = np.array([0])

# with内のみzero divideのwarningを無視
with np.errstate(divide='ignore'):
# 無限大(np.inf)かどうかのチェック
if( x / y == np.inf ):
print( 'inf' )
else:
print( x / y )

print( "処理終了" )

実行するとこうなります。numpyで0除算した値は、numpy.infになるためif文でのハンドリングが可能です。

$ ./zerodivide_numpy_nowarning.py
inf
処理終了

関連記事)python入門