numpyなしのPythonで変数NaNを割り当てる


103

ほとんどの言語には、変数に値NaNを割り当てるために使用できるNaN定数があります。Pythonはnumpyを使用せずにこれを行うことができますか?


1
C、C ++、java、C#、ocaml、それは多くの言語の一部です。
zelinka 2013年

2
Cでは、NaNはNAN; これはmath.h、C99以降、で定義された定数です。(その言語として最新の標準化されたバージョンをその言語と呼ぶのは公平だと思います。したがって、「C」はC11です。)(stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-inを参照)-c); C ++で、それはだNANとしても、そこにもだnan()nanf()nanl()私は少し少ない特定の彼らは何をすべきかについてのだけれども、。double.NaNJava、Double.NaNC#…
Thanatos、2015

回答:


168

はい-使用しますmath.nan

>>> from math import nan
>>> print(nan)
nan
>>> print(nan + 2)
nan
>>> nan == nan
False
>>> import math
>>> math.isnan(nan)
True

Python 3.5より前は、使用できましたfloat("nan")(大文字と小文字は区別されません)。

NaNである2つのものが互いに等しいかどうかを確認すると、常にfalseが返されることに注意してください。これは、「数ではない」2つの要素が(厳密に言えば)互いに等しいとは言えないためです。IEEE754NaN値に対してfalseを返すすべての比較の根拠何ですか?を参照してください詳細と情報については。

代わりに、math.isnan(...)値がNaNかどうかを判断する必要がある場合に使用します。

さらに、==NaN値に対する操作の正確なセマンティクスは、listor などのコンテナータイプ内にNaNを格納しようとする場合dict(またはカスタムコンテナータイプを使用する場合)に、微妙な問題を引き起こす可能性があります。詳細については、コンテナ内のNaNの存在の確認を参照してください。


Pythonのdecimalモジュールを使用してNaN数を作成することもできます:

>>> from decimal import Decimal
>>> b = Decimal('nan')
>>> print(b)
NaN
>>> print(repr(b))
Decimal('NaN')
>>>
>>> Decimal(float('nan'))
Decimal('NaN')
>>> 
>>> import math
>>> math.isnan(b)
True

math.isnan(...) Decimalオブジェクトでも機能します。


ただし、Pythonの分数モジュールでNaN数を作成することはできません

>>> from fractions import Fraction
>>> Fraction('nan')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 146, in __new__
    numerator)
ValueError: Invalid literal for Fraction: 'nan'
>>>
>>> Fraction(float('nan'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 130, in __new__
    value = Fraction.from_float(numerator)
  File "C:\Python35\lib\fractions.py", line 214, in from_float
    raise ValueError("Cannot convert %r to %s." % (f, cls.__name__))
ValueError: Cannot convert nan to Fraction.

ちなみに、あなたも行うことができfloat('Inf')Decimal('Inf')またはmath.inf(3.5+)は無限の番号を割り当てます。(また参照してくださいmath.isinf(...)

しかし、やってFraction('Inf')Fraction(float('inf'))許可されていないし、ちょうどNaNのように、例外がスローされます。

数値がNaNでも無限でもないことをすばやく簡単に確認する方法が必要な場合はmath.isfinite(...)、Python 3.2以降で使用できます。


複素数で同様のチェックを行う場合、cmathモジュールにはモジュールと同様の関数と定数のセットが含まれていmathます。


2
float( 'nan)を使用すると、np.nanを使用するよりも3倍遅く、nan = float(' nan ')を1回割り当ててから、変数' nan 'を次のすべての割り当てに使用するよりも約6.5倍遅いことに注意してください(barnert's回答)。
Daniel Goldfarb

18
nan = float('nan')

そして今、あなたは定数を持っています、nan

同様に、decimal.DecimalのNaN値を作成できます。

dnan = Decimal('nan')

これは複数のnan割り当ての最も効率的な答えです。つまり、float( 'nan')を1回だけ使用し、残りのすべての割り当てに割り当てられた定数を使用します。ただし、nan totalの割り当てが1つまたは2つしかない場合は、numpy.nanを使用するのが最も高速です。
Daniel Goldfarb



6

「inf-inf」からNaNを取得でき、2e308より大きい数から「inf」を取得できるため、通常は次のように使用します。

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan

3
この回答は不当に反対票を投じた。.txtファイルで多数の小さな解析テストを記述し、予想される出力部分を取得するためにast.literal_evalを使用しています。そこでfloat( 'nan')を呼び出すことは不可能であり、この答えは私にとって役に立ちました。
Vitalik Verhovodov 2018年

0

infと-infを生成するためのより一貫した(そして不透明度が低い)方法は、再びfloat()を使用することです。

>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf

フロートのサイズはアーキテクチャによって異なるため、9e999のようなマジックナンバーを使用することは、それが機能する可能性があるとしても、避けるのが最善です。

import sys
sys.float_info
sys.float_info(max=1.7976931348623157e+308,
               max_exp=1024, max_10_exp=308,
               min=2.2250738585072014e-308, min_exp=-1021,
               min_10_exp=-307, dig=15, mant_dig=53,
               epsilon=2.220446049250313e-16, radix=2, rounds=1)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.