【Python】NaNとは?その判定方法や削除方法まで実例付きで解説

※本サイトにはプロモーション・広告が含まれています。

(最終更新日:2023年6月)

✔このような方へ向けて書かれた記事となります

「pythonでnanをどのように判定するのだろうか?」
「pythonでnanを判定する方法が知りたい」
「pythonでnan判定の実例が見たい」

✔当記事を通じてお伝えすること

  • pythonでnanの基本的な判定方法
  • pythonでnan判定の書き方やその応用
  • pythonでnan判定の実例

当記事では、pythonでnan判定を行う基本的な方法から、さまざまな応用まで、具体的な例を用いて詳しく解説しています。

ぜひ最後までご覧ください。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

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でのデータ分析や数値計算をスムーズに行えるようになりましょう。

タイトルとURLをコピーしました