LoginSignup
47
35

More than 3 years have passed since last update.

Pythonでnanの扱いにハマったので、その備忘録。。

Last updated at Posted at 2019-10-03

はじめに

Pythonにてデータ処理をしていたある日、ループ回数がおかしいことに気づく。
ループ回数が異常に多い原因がnanの値が格納されているためと気づき、nanとなった時にループを抜けるという方法の実装に、馬鹿みたいに時間を要したので、その備忘録的なあれです。
(※対処方法はいくつかあると思いますので、その一例を示します。)

1.とりあえず、結論!

次のコードで判定することが可能でした。(判定したい値=nanでTrue)

code.py
import math
math.isnan("判定したい値") # nanの時True

2.nanって何??

「nanって何?」って話なのですが、数みたいなものです。

どんな時に発生するか(例)
・計算不能になった時
・値の入っていないデータを取り込んだ時

、、、他にもいろんな場面で発生すると思います。
プログラム経験者であれば、何度かこの手の処理を扱ったことがあるのでは?と思います。
実際、自分も過去に対処した方法を試みたのですが、Pythonでは上手くいきませんでした。

3.if 値 !="nan" ではダメな理由

まず、単純に判定したい値がnanであるかどうかを判定してみました。

(追記:@konandoiruasa 様に"=="ではなく"is"を使えば、value is np.nan でtrueとなるとのことを教えていただきました。ありがとうございます。)

code.py
import numpy as np

value=np.nan
print(value == "nan")
print(value == np.nan)
print(value is np.nan)
Result
False
False
True

一つ目は、nanという予約語で判定を行いました。(C言語とかはこれでいけるはず)
二つ目は、代入値と同じ値で判定を行いました。

見ての通りですが、いずれもTrueと返ってこない。。
なんで??って感じでした。

「あれ? "nan" って 何型?文字なのか数値なのか?」 ふとそんな疑問が浮かびました。
もし文字なら、文字で判定を行えるのでは?とかそんなこと思いましたが、

code.py
import numpy as np

value=np.nan
print(type(value))
Result
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()を使うのが良さそうですね!

47
35
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
35