Pythonで無限大(inf)と非数(nan)を扱う方法:float と math モジュール

Pythonの数値型 float(浮動小数点数)は、3.14-0.5 といった通常の数値に加え、「無限大」や「非数 (Not a Number)」といった特殊な状態を表現できます。

これらは、数学的な計算(ゼロ除算の試み)や、データ分析における欠損値の処理などで利用されます。

この記事では、inf (無限大) と nan (非数) の作成方法、それらの演算における振る舞い、そして判定方法について解説します。

目次

無限大 (inf) の作成と性質

無限大(Infinity)は、float('inf') という文字列を float コンストラクタに渡すことで作成できます。

# 正の無限大
pos_inf = float('inf')
# 負の無限大
neg_inf = float('-inf')

print(f"正の無限大: {pos_inf}")
print(f"負の無限大: {neg_inf}")
print(f"型: {type(pos_inf)}")

実行結果:

正の無限大: inf
負の無限大: -inf
型: <class 'float'>

math モジュールをインポートすれば、math.inf として直接利用することも可能です。

inf の演算

無限大は、ほとんどの演算において無限大のままです。

# 無限大に数を足しても無限大
print(f"inf + 10000 = {pos_inf + 10000}")

# 無限大に数を掛けても無限大
print(f"inf * 500 = {pos_inf * 500}")

# 無限大を(有限の)数で割っても無限大
print(f"inf / 123 = {pos_inf / 123}")

# 無限大同士の加算
print(f"inf + inf = {pos_inf + pos_inf}")

実行結果:

inf + 10000 = inf
inf * 500 = inf
inf / 123 = inf
inf + inf = inf

非数 (nan) の作成と性質

非数(Not a Number)は、float('nan') で作成できます。nan は、計算結果が「(実数として)定義できない数値」であることを示すために使われます。

nan が発生するケース

nan は、以下のような数学的に「不定形」となる計算で発生します。

# 0.0 / 0.0
nan_val_1 = 0.0 / 0.0

# inf - inf
nan_val_2 = float('inf') - float('inf')

# inf / inf
nan_val_3 = float('inf') / float('inf')

print(f"0.0 / 0.0 = {nan_val_1}")
print(f"inf - inf = {nan_val_2}")
print(f"inf / inf = {nan_val_3}")

実行結果:

0.0 / 0.0 = nan
inf - inf = nan
inf / inf = nan

nan の演算(伝播性)

nan は「伝播性」を持ちます。nan が含まれる演算の結果は、ほぼ全て nan になります。

base_nan = float('nan')
print(f"nan + 50 = {base_nan + 50}")
print(f"nan * 0 = {base_nan * 0}") # 0を掛けても nan

実行結果:

nan + 50 = nan
nan * 0 = nan

infnan の判定方法

infnan はデータ処理において特別な対応が必要な場合が多いため、これらを正しく判定する方法が重要です。判定には math モジュールを使います。

import math

val_inf = float('inf')
val_nan = float('nan')
val_num = 100.0

# isinf() : 無限大かどうかを判定
print(f"math.isinf({val_inf}): {math.isinf(val_inf)}") # True
print(f"math.isinf({val_num}): {math.isinf(val_num)}") # False

# isnan() : 非数かどうかを判定
print(f"math.isnan({val_nan}): {math.isnan(val_nan)}") # True
print(f"math.isnan({val_inf}): {math.isnan(val_inf)}") # False

nan 判定における最重要注意点

nan を判定する際、== 演算子を使ってはいけません。nan は**自分自身と比較しても等しくならない(False を返す)**という特殊な性質を持っています。

test_nan = float('nan')

# '==' を使った誤った判定
print(f"test_nan == float('nan') : {test_nan == float('nan')}") # False
print(f"test_nan == test_nan : {test_nan == test_nan}")     # False

nan かどうかを確実に判定するには、必ず math.isnan() を使用してください。

実用例:安全なデータ集計

データリストに infnan が含まれている場合、sum() などが意図通りに動作しません。これらを判定して除外する処理の例です。

import math

def calculate_safe_average(data_list):
    """
    inf や nan を除外して平均値を計算する
    """
    total = 0
    count = 0
    for value in data_list:
        # inf や nan を判定してスキップ
        if math.isinf(value) or math.isnan(value):
            print(f"スキップ: {value}")
            continue
        
        total += value
        count += 1
        
    if count == 0:
        return 0.0 # または nan を返す
        
    return total / count

# --- 実行 ---
raw_data = [15.5, 20.0, float('inf'), 10.0, float('nan'), 5.5, float('-inf')]
average = calculate_safe_average(raw_data)

print(f"処理済みデータ: {raw_data}")
print(f"安全な平均値: {average}")

実行結果:

スキップ: inf
スキップ: nan
スキップ: -inf
処理済みデータ: [15.5, 20.0, inf, 10.0, nan, 5.5, -inf]
安全な平均値: 12.75

まとめ

  • 無限大は float('inf') または math.inf で作成します。
  • 非数(Not a Number)は float('nan') または math.nan で作成します。0/0inf-inf などの不定形の計算結果としても生じます。
  • infnan の判定には、math.isinf()math.isnan() を使用します。
  • nan == nanFalse になるため、==nan を判定してはいけません。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次