はじめに
Pythonにてデータ処理をしていたある日、ループ回数がおかしいことに気づく。
ループ回数が異常に多い原因がnanの値が格納されているためと気づき、nanとなった時にループを抜けるという方法の実装に、馬鹿みたいに時間を要したので、その備忘録的なあれです。
(※対処方法はいくつかあると思いますので、その一例を示します。)
#1.とりあえず、結論!
次のコードで判定することが可能でした。(判定したい値=nanでTrue)
import math
math.isnan("判定したい値") # nanの時True
#2.nanって何??
「nanって何?」って話なのですが、数みたいなものです。
どんな時に発生するか(例)
・計算不能になった時
・値の入っていないデータを取り込んだ時
、、、他にもいろんな場面で発生すると思います。
プログラム経験者であれば、何度かこの手の処理を扱ったことがあるのでは?と思います。
実際、自分も過去に対処した方法を試みたのですが、Pythonでは上手くいきませんでした。
#3.if 値 !="nan" ではダメな理由
まず、単純に判定したい値がnanであるかどうかを判定してみました。
(追記:@konandoiruasa 様に"=="ではなく"is"を使えば、value is np.nan でtrueとなるとのことを教えていただきました。ありがとうございます。)
import numpy as np
value=np.nan
print(value == "nan")
print(value == np.nan)
print(value is np.nan)
False
False
True
一つ目は、nanという予約語で判定を行いました。(C言語とかはこれでいけるはず)
二つ目は、代入値と同じ値で判定を行いました。
見ての通りですが、いずれもTrueと返ってこない。。
なんで??って感じでした。
「あれ? "nan" って 何型?文字なのか数値なのか?」 ふとそんな疑問が浮かびました。
もし文字なら、文字で判定を行えるのでは?とかそんなこと思いましたが、
import numpy as np
value=np.nan
print(type(value))
float
って、まぁそりゃそうよな、って感じでfloat型という想定内の結果に。
nanを代入した変数の型 → float型
nan同士( np.nanを代入したもの と np.nan )での比較 → false
これを見る限り、Pythonではnanに一意の値が振られていないように見えますね。
自分はてっきり一意の値が振られていると思い込んでいたため、この判定に苦労しました。
みなさんも気を付けてくださいね。
#4.Pythonでのnanのイメージ
結局、Pythonでのnanって何?ってところに戻りますが、
「数みたいなもの」と表現するしかなさそうです。
ちなみに、Pythonではnanを非数というようです。
ただ一つ重要な性質として、
非数と非数が比較されたときにはFalseを返すという規則が存在することです。
したがって、nanの判定には変数の型(扱うデータがfloat型でない場合は、float型=nanと識別可能)
または、冒頭の**math.isnan()**を使うのが良さそうですね!