(最終更新日:2023年6月)
✔このような方へ向けて書かれた記事となります
「pythonでnanをどのように判定するのだろうか?」
「pythonでnanを判定する方法が知りたい」
「pythonでnan判定の実例が見たい」
✔当記事を通じてお伝えすること
- pythonでnanの基本的な判定方法
- pythonでnan判定の書き方やその応用
- pythonでnan判定の実例
当記事では、pythonでnan判定を行う基本的な方法から、さまざまな応用まで、具体的な例を用いて詳しく解説しています。
ぜひ最後までご覧ください。
NaN(Not a Number)とは?
こちらでは、「NaN」についてお伝えしていきます。
NaNの特性を理解することは、データ解析や機械学習のプロジェクトを進める上で重要です。
- 浮動小数点数float型の非数NaN
- NaNの生成方法
浮動小数点数float型の非数NaN
PythonにおけるNaN(Not a Number)は、IEEE 754規格の浮動小数点数の特殊な値で、数学的に未定義の演算結果を表します。
IEEE 754規格とは、浮動小数点数の扱い方・演算方法などを定める規格のことをいいます。
0で割った結果や無限大から無限大を引くなど、通常の数学の範囲を超える演算の結果としてNaNが出ることがあります。
NaNの生成方法
PythonにおいてNaNはfloat型で表現され、直接float('nan')
を使って生成できます。
例えば、0で割る演算0.0 / 0.0や、無限大の減算float(‘inf’) – float(‘inf’)などです。
import math
# 0で割る演算
result = 0.0 / 0.0
print(result) # NaN
# 無限大の減算
result = float('inf') - float('inf')
print(result) # NaN
# mathモジュールのnan関数を使ってもNaNを生成できる
result = math.nan
print(result) # NaN
算術演算の結果としてもNaNが生成されます。
NaNの判定方法
NaNの判定方法について解説します。
NaNは数値ではないため、通常の比較演算子では正しく判定できないからです。
- math.isnan()関数を使った判定
- NumPy(np.isnan()関数)を使った判定
- 比較演算子(<, >, ==, !=)に対するNaNの振る舞い
- if文でのNaN判定
math.isnan()関数を使った判定
Pythonのmathモジュールにはisnan()
という関数があります。
NaNを判定するための関数です。
import math
print(math.isnan(float('nan')))
#True
NumPy(np.isnan()関数)を使った判定
NumPyもまた、isnan()
関数を提供しています。
リストや配列など、複数の要素を一度に判定する際に便利です。
import numpy
print(numpy.isnan(numpy.array([1.0, numpy.nan, 3.0])))
#array([False, True, False])
比較演算子(<, >, ==, !=)に対するNaNの振る舞い
NaNは一般的な比較演算子での振る舞いが特異で、自分自身との比較でさえFalseを返します。
print(float('nan') == float('nan'))
#False
例えこの特性は、NaNを判定する際に注意が必要です。
if文でのNaN判定
NaNをif文で判定する場合も特異な動きを見せます。
if文では、NaNが”正”と評価されるのです。
>>> if float('nan'):
... print('True')
...
True
これはNaNが0やNoneなどとは違って”存在している”と評価されるためです。
NaNをリストから削除・置換する方法
こちらは、リスト内のnanを操作する方法についてみていきましょう。
リスト操作の際にはNaNの特性を理解し、適切な操作をおこなうことが重要です。
- リスト中のNaNの処理方法
- NaNを含む演算
- Nanの置換
リスト中のNaNの処理方法
PythonのリストからNaNを削除する場合、isnan()
関数とリスト内包表記を組み合わせられます。
[x for x in list if not math.isnan(x)]
リストからNaNを取り除いた新しいリストが得られます。
import math
# リストの作成(NaNを含む)
my_list = [1.0, 2.0, float('nan'), 3.0, float('nan'), 4.0]
# NaNを削除した新しいリストの作成
new_list = [x for x in my_list if not math.isnan(x)]
print(new_list)
NaNを含む演算
NaNを含む数値計算を行うと、結果は常にNaNになります。
例えば、10 + float('nan')
やnumpy.mean([1, 2, numpy.nan, 4])
といった演算の結果はNaNです。
import numpy
# 10 + NaN
result1 = 10 + float('nan')
print(result1) # 結果: nan
# 平均値の計算(NaNを含む)
my_list = [1, 2, numpy.nan, 4]
result2 = numpy.mean(my_list)
print(result2) # 結果: nan
これは、数値ではないNaNが計算に含まれているためです。
これを避けるためには、演算前にNaNを除去したり、適切な値に置換する処理が必要です。
NaNの計算を回避する方法はこちらも参考にしてください。
import numpy as np
value1 = 10
value2 = np.nan
if np.isnan(value1) or np.isnan(value2):
result = np.nan
else:
result = value1 + value2
NaNの置換
NaNを特定の値(例えば0や平均値など)で置換できます。
NumPyのnan_to_num()
関数を使用すると、NaNを指定した値に置き換えましょう。
import numpy as np
my_array = np.array([1, 2, np.nan, 4])
clean_array = np.nan_to_num(my_array, nan=0)
NaNの扱いを理解する:参考情報
NaNの扱いは一見難しそうに感じるかもしれませんが、慣れるとデータ分析における重要なスキルとなります。
ここでは、NaNの理解を深めるための参考情報をみていきましょう。
- NoneとNaNの違い
- 自身を比較した場合のnumpy.nanの挙動
- データサイエンスでのNaNの扱い
NoneとNaNの違い
Pythonでは、NoneもNaNも「ない」状態を表すために使われますが、それぞれの挙動や用途は異なります。
NoneはPythonの組み込み型で、何も存在しないことを表すもの。
NaNは浮動小数点数で、数値演算の結果として「未定義」を表すために使用されます。
#None
#変数が値を持たない場合や、関数の戻り値が存在しない場合に使用されます。
#条件式ではFalseと評価されます。
#Noneを他のオブジェクトと比較する場合、is演算子を使用する必要があります(==ではなく)。
my_variable = None
if my_variable is None:
print("my_variableは存在しません")
例えば、0で除算した結果や無限大から無限大を引いた結果などはNaNとなります。
自身を比較した場合のnumpy.nanの挙動
NaNは自身との比較でもFalseを返すと説明しましたが、NumPyではこれを利用してNaNを検出できます。
具体的には、numpy.isnan(x)やx != xという形でNaNを判別できるのです。
import numpy as np
x = np.array([1, 2, np.nan, 4])
# numpy.isnan()を使用してNaNを検出
nan_mask = np.isnan(x)
print(nan_mask) # [False False True False]
# x != xを使用してNaNを検出
nan_mask = x != x
print(nan_mask) # [False False True False]
# NaNを含む要素のインデックスを取得
nan_indices = np.where(nan_mask)
print(nan_indices) # (array([2]),)
データサイエンスでのNaNの扱い
データサイエンスでは、NaNはしばしば欠損値や不明なデータを表すために使われます。
pandasやNumPyには、NaNの扱いに便利なメソッドが備わっているのです。
#pandas
import pandas as pd
import numpy as np
# NaNを含むシリーズを作成
s = pd.Series([1, 2, np.nan, 4])
# 欠損値の判定
print(s.isna()) # 欠損値の場所にTrueを示すブールシリーズを返す
# 欠損値の除外
s_cleaned = s.dropna() # 欠損値を除外したシリーズを返す
print(s_cleaned)
# 欠損値の穴埋め
s_filled = s.fillna(0) # 欠損値を指定した値で穴埋めしたシリーズを返す
print(s_filled)
例えば、pandasではdropna()
でNaNを含む行または列を削除したり、fillna()
でNaNを他の値に置換することができます。
まとめ:PythonでNaNをうまく扱おう
当記事では、PythonのNaNについて以下を解説してきました。
- その生成方法
- 判定方法
- リストからの削除や置換方法
NaNは特殊な値であるため、その挙動を理解して適切に扱うことは重要です。
import math
import numpy as np
# NaNの生成
nan_value = float('nan')
print(nan_value) # NaN
# NaNの判定
print(math.isnan(nan_value)) # True
# リストからNaNを削除する
values = [1, 2, np.nan, 4, np.nan]
values_without_nan = [x for x in values if not math.isnan(x)]
print(values_without_nan) # [1, 2, 4]
# リスト内のNaNを別の値に置換する
values_replaced = [x if not math.isnan(x) else 0 for x in values]
print(values_replaced) # [1, 2, 0, 4, 0]
これらの知識を活かし、Pythonでのデータ分析や数値計算をスムーズに行えるようになりましょう。