Python'da numpy olmadan değişken NaN atama


103

Çoğu dilde, bir değişkene NaN değerini atamak için kullanabileceğiniz bir NaN sabiti vardır. Python bunu numpy kullanmadan yapabilir mi?


1
C, C ++, java, C #, ocaml, pek çok dilin bir parçasıdır.
zelinka

2
NaN, C cinsinden NAN; math.hC99 itibariyle tanımlanmış bir sabittir . (Dilin en son standartlaştırılmış sürümünü bu dil olarak adlandırmanın adil olduğunu düşünüyorum. Bu nedenle "C", C11'dir.) (Bkz. Stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in -c ); C ++, bu kadar NANiyi, orada da olduğu gibi nan(), nanf()ve nanl()ben biraz daha az belli yaptıklarını olarak değilim ama. double.NaNJava'da, Double.NaNC #
dilinde

Yanıtlar:


169

Evet - kullanın 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'ten önce kullanılabilir float("nan") (büyük / küçük harfe duyarlı değildir).

NaN olan iki şeyin birbirine eşit olup olmadığını kontrol etmenin her zaman yanlış döndüreceğini unutmayın. Bunun nedeni kısmen "sayı olmayan" iki şeyin birbirine eşit olduğunun söylenemeyeceğidir (kesinlikle) - bkz . IEEE754 NaN değerleri için yanlış döndüren tüm karşılaştırmaların mantığı nedir? daha fazla ayrıntı ve bilgi için.

Bunun yerine, math.isnan(...)bir değerin NaN olup olmadığını belirlemeniz gerekiyorsa kullanın.

Ayrıca, ==NaN değerindeki işlemin tam anlam bilgisi , NaN'yi listveya gibi kap türleri içinde depolamaya çalışırken dict(veya özel kap türleri kullanılırken) ince sorunlara neden olabilir . Daha fazla ayrıntı için Kapta NaN varlığını kontrol etme konusuna bakın .


Python'un ondalık modülünü kullanarak NaN sayıları da oluşturabilirsiniz :

>>> 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 nesnelerle de çalışacaktır.


Ancak, olamaz Python'un içinde NaN numaraları inşa kesirler modülü:

>>> 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.

Bu arada, siz de yapabilirsiniz float('Inf'), Decimal('Inf')veya math.inf(3.5+) sonsuz numaraları atamak için. (Ve ayrıca bakınız math.isinf(...))

Ancak yapmak Fraction('Inf')ya Fraction(float('inf'))da izin verilmez ve tıpkı NaN gibi bir istisna atar.

Bir sayının NaN ya da sonsuz olmadığını kontrol etmenin hızlı ve kolay bir yolunu istiyorsanız math.isfinite(...), Python 3.2+ ile birlikte kullanabilirsiniz.


Karmaşık sayılarla benzer kontroller yapmak istiyorsanız, cmathmodül , modüle benzer bir dizi işlev ve sabit içerir math:


2
Float ('nan) kullanmanın np.nan kullanmaktan 3 kat daha yavaş olduğunu ve nan = float (' nan ') atamaktan yaklaşık 6.5 kat daha yavaş olduğunu ve ardından sonraki tüm atamalar için' nan 'değişkenini kullanmanın (abarnert's Cevap).
Daniel Goldfarb

18
nan = float('nan')

Ve şimdi sabite sahipsiniz nan.

Benzer şekilde ondalık için NaN değerleri oluşturabilirsiniz.

dnan = Decimal('nan')

Bu, birden çok nan ataması için en etkili cevaptır: Yani, float ('nan') 'ı yalnızca bir kez kullanın ve ardından kalan tüm atamalar için atanan sabiti kullanın. Bununla birlikte, yalnızca bir veya iki nan toplam ataması yapıyorsanız, numpy.nan kullanmak en hızlı yoldur.
Daniel Goldfarb

7

Kullanım float("nan"):

>>> float("nan")
nan


6

NaN'yi "inf - inf" den ve "inf" yi 2e308'den büyük bir sayıdan elde edebilirsiniz, bu yüzden genellikle şunu kullandım:

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

3
Bu cevap mantıksız bir şekilde olumsuz oylandı. .Txt dosyalarına çok sayıda küçük ayrıştırma testi yazıyorum ve beklenen çıktı bölümünü elde etmek için ast.literal_eval kullanıyorum. Orada float ('nan') diye çağırmak imkansız ve bu cevap benim için yardımcı oldu.
Vitalik Verhovodov

0

İnf ve -inf oluşturmanın daha tutarlı (ve daha az opak) bir yolu tekrar float () kullanmaktır:

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

Bir şamandıranın boyutunun mimariye bağlı olarak değiştiğini unutmayın, bu nedenle işe yarayacak olsa bile 9e999 gibi sihirli sayıları kullanmaktan kaçınmak en iyisidir.

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.