NaN değerlerini nasıl kontrol edebilirim?


Yanıtlar:


1278

math.isnan (x)

TrueX bir NaN ise (sayı değil), Falseaksi halde geri dönün .

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True

5
@ charlie-parker: Python3'te math.isnan hala matematik modülünün bir parçasıdır. docs.python.org/3/library/math.html#math.isnan . İsterseniz numpy.isnan kullanın, bu cevap sadece bir öneri.
gimel

2
@ SittingBull Bkz. Docs.python.org/3/library/functions.html#float "Bağımsız değişken bir dize ise, ondalık sayı içermeli" veya "Sonsuzluk" "inf" "nan" olmalıdır
gimel

35
olduğu math.isnantercih np.isnan()?
TMWP

34
@TMWP muhtemelen ... import numpyyaklaşık 15 MB RAM alırken import math, yaklaşık 0,2 MB alır
petrpulc

9
@TMWP: NumPy kullanıyorsanız, numpy.isnanNumPy dizilerini işlediği için üstün bir seçimdir. Eğer numpy kullanmıyorsanız, büyük ihtimalle bir NumPy bağımlılık alarak ve sadece NaN kontrolü için numpy yüklemek için vakit (ancak NaN denetimler yapar kod tür yazıyorsanız, bu kadar hiçbir yararı yoktur gerektiğini kullanıyor Dizi).
user2357112 Monica

359

Bir NaN'yi test etmenin olağan yolu, kendisine eşit olup olmadığını görmektir:

def isNaN(num):
    return num != num

8
Uyarı kelimesi: Bear'ın yorumundan alıntı: "Python <= 2.5 ile sıkışmış insanlar için. Nan! = Nan güvenilir bir şekilde çalışmadı. Bunun yerine numpy kullanıldı." Bunu söyledikten sonra, aslında başarısız olduğunu hiç görmedim.
mavnn

22
Operatörün aşırı yüklenmesi nedeniyle, bu işlevi karıştırmamın birçok yolu olduğundan eminim. math.isnan () ile git
djsadinoff

4
Yukarıda belirtilen 754 spesifikasyonunda NaN == NaN'nin her zaman böyle olmamasına rağmen her zaman yanlış olması gerektiğini söylüyor. Matematiğin ve / veya numpy'nin kaputun altında bunu nasıl kontrol etmesi mümkün değil mi?
Hari Ganesan

Teşekkürler . Bu aynı zamanda bir skaler üzerinde işlem yapıyorsanız np.isnan kullanmaya göre 15-20x kat daha hızlıdır
thomas.mac

5
Bu işe yarar ve bir dereceye kadar mantıklı olsa da, ben prensipleri olan bir insanım ve bunu yasaklı büyücülük olarak ilan ediyorum. Lütfen bunun yerine math.isnan kullanın.
Gonzalo

152

numpy.isnan(number)size olup olmadığını söyler NaN.


3
Python sürüm 2.7 de çalışır.
Michel Keijzers

6
numpy.all(numpy.isnan(data_list))listedeki tüm öğelerin nan olup olmadığını belirlemeniz gerekirse de yararlıdır
Jay P.

3
NumPy'ye gerek yok:all(map(math.isnan, [float("nan")]*5))
sleblanc

6
Bu cevap 6 yıl önce yazıldığında, Python 2.5 hala ortak kullanımdaydı ve math.isnan standart kütüphanenin bir parçası değildi. Bugünlerde pek çok yerde böyle olmadığını umuyorum!
mavnn

4
np.isnan () işlevinin ondalık işleme koymadığına dikkat edin. math.isnan () işlemektedir.
comte

55

Burada bir değişkeni test edebileceğiniz üç yol "NaN" dir.

import pandas as pd
import numpy as np
import math

#For single variable all three libraries return single boolean
x1 = float("nan")

print(f"It's pd.isna  : {pd.isna(x1)}")
print(f"It's np.isnan  : {np.isnan(x1)}")
print(f"It's math.isnan : {math.isnan(x1)}")

Çıktı

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True

2
pd.isna (değer) çok fazla sorun kaydetti! bir cazibe gibi çalışıyor!
abhishake

1
ps.isna()sorunlarımı çözer. Teşekkürler!
06:16

32

İşte bir cevap:

  • IEEE 754 standardına uygun NaN uygulamaları
    • yani: python en NaN: float('nan'), numpy.nan...
  • başka herhangi bir nesne: dize veya herhangi bir şey (karşılaşıldığında istisnalar oluşturmaz)

Standardı takiben uygulanan bir NaN, kendisiyle eşitsizlik karşılaştırmasının True döndürmesi gereken tek değerdir:

def is_nan(x):
    return (x != x)

Ve bazı örnekler:

import numpy as np
values = [float('nan'), np.nan, 55, "string", lambda x : x]
for value in values:
    print(f"{repr(value):<8} : {is_nan(value)}")

Çıktı:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False

1
Kontrol ettiğim dizi eksik değerlere sahip dizeler 'nans' (???) yani bu çözüm diğerlerinin başarısız olduğu yerlerde çalışıyor.
keithpjolley

numpy.nannormal bir Python floatnesnesidir, tıpkı döndürülen tür gibi float('nan'). NumPy'de karşılaştığınız çoğu NaN numpy.nannesne olmayacaktır .
user2357112 Monica

numpy.nanNaN değerini C'deki temel kütüphanede kendi başına tanımlar . Python'un NaN'sini sarmaz. Ama şimdi, ikisi de C99 API'sine bağlı oldukları için IEEE 754 standardına uyuyor.
x0s

Monica: Python ve numpy NaN aslında aynı şekilde davranmıyor: float('nan') is float('nan')(benzersiz olmayan) ve np.nan is np.nan(benzersiz)
x0s

@ x0s: Bunun NumPy ile bir ilgisi yok. np.nanher float('nan')çağrı yeni bir nesne oluştururken belirli bir nesnedir. Eğer yapsaydın nan = float('nan'), o zaman sen nan is nande alırsın . Bir inşa halinde fiili gibi bir şeyle NumPy NaN np.float64('nan')sonra olsun istiyorum np.float64('nan') is not np.float64('nan')çok .
user2357112 Monica

28

Aslında bununla karşılaştım, ama benim için nan, -inf veya inf'yi kontrol ediyordu. Az önce kullandım

if float('-inf') < float(num) < float('inf'):

Bu sayılar için doğrudur, nan ve her ikisi de inf için yanlıştır ve dizeler veya diğer türler (muhtemelen iyi bir şey) gibi şeyler için bir istisna oluşturur. Ayrıca bu, matematik veya numpy gibi herhangi bir kütüphanenin içe aktarılmasını gerektirmez (numpy çok büyüktür, herhangi bir derlenmiş uygulamanın boyutunu iki katına çıkarır).


9
math.isfinitePython 3.2'ye kadar tanıtılmadı, bu yüzden @DaveTheScientist'in cevabı 2012'de yayınlandığında tam olarak "tekerleği yeniden icat" değildi - çözüm hala Python 2 ile çalışanlar için duruyor
sudo_coffee

22

math.isnan ()

veya sayıyı kendisiyle karşılaştırın. NaN daima! = (O takdirde örneğin NaN, aksi olan bir sayı) karşılaştırma başarılı olması gerekir.


6
Python ile sıkışmış insanlar için <= 2.5. Nan! = Nan güvenilir bir şekilde çalışmadı. Bunun yerine numpy kullanıldı.
Ayı

16

Başka bir yöntem <2.6'da takılı kalırsanız, numpy'niz yoktur ve IEEE 754 desteğiniz yoktur:

def isNaN(x):
    return str(x) == str(1e400*0)

12

Ben bu yazı girdi, çünkü ben fonksiyonu ile bazı sorunlar yaşadım:

math.isnan()

Bu kodu çalıştırdığınızda sorun var:

a = "hello"
math.isnan(a)

İstisna doğurur. Benim çözümüm başka bir kontrol yapmak:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)

3
Muhtemelen aşağı indirilmiştir çünkü isnan () bir dize değil, bir şamandıra alır. İşlevle ilgili yanlış bir şey yok ve sorunlar sadece onu kullanma girişiminde. (Bu özel kullanım durumunda çözümü geçerlidir, ancak bu sorunun cevabı değildir.)
Peter Hansen

6
Türleri bu şekilde kontrol ederken dikkatli olun. Bu, örneğin numpy.float32 NaN'ler için çalışmaz. İnşaat dışında bir denemek / kullanmak daha iyi: def is_nan(x): try: return math.isnan(x) except: return False
Rob

3
NaN, bir değerin geçerli bir sayı olmadığı anlamına gelmez. Belirli bir sonucun tanımsız olduğunu belirtmek IEEE kayan nokta temsilinin bir parçasıdır. örneğin 0 / 0. Bu nedenle "merhaba" nın nan olup olmadığını sormak anlamsızdır.
Brice M. Dempsey

2
bu daha iyi çünkü NaN herhangi bir dizge, ints veya şamandıra listesine
inebilir

Pandalarda dize sütunları işlemek için tam olarak bu uygulamak zorunda kaldı.
Cristian Garcia

7

Python <2.6 ile bitirdim

def isNaN(x):
    return str(float(x)).lower() == 'nan'

Bu benim için bir Solaris 5.9 kutusunda python 2.5.1 ve Ubuntu 10'da python 2.6.5 ile çalışıyor


6
Windows bazen bunu çağırdığı için bu çok taşınabilir değil-1.#IND
Mike T

5

NaNDize olarak gönderen bir web hizmetinden veri alıyorum 'Nan'. Ancak verilerimde başka tür dizeler de olabilir, bu nedenle basit float(value)bir istisna fırlatabilir. Kabul edilen cevabın aşağıdaki varyantını kullandım:

def isnan(value):
  try:
      import math
      return math.isnan(float(value))
  except:
      return False

Gereksinimi:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True

1
ortry: int(value)
chwi

@chwi öyleyse öneriniz valuevarlık hakkında ne söylüyor NaN?
Mehdi

Eh, "bir sayı değil" olarak, bir int için döküm olamaz bir şey aslında bir sayı değil ve try deyimi başarısız olur? Yanlış döndürme dışında true döndürmeyi deneyin.
chwi

@chwi Kelimenin tam anlamıyla "bir sayı değil" alarak haklısınız, ama buradaki nokta bu değil. Aslında, tam olarak anlambiliminin ne olduğunu arıyorum NaN(python'da ne elde edebileceğiniz gibi float('inf') * 0) ve böylece 'Merhaba' bir sayı olmamasına rağmen, aynı zamanda hala sayısal bir değer NaNolduğu NaNiçin değil !
Mehdi

@chwi: Kural dışı durum işleme belirli bir kural dışı durum içinse, haklısınız. Ancak bu cevapta genel istisna ele alınmıştır. Bu yüzden kontrol etmeye gerek yok int(value)Tüm istisnalar Falseiçin yazılır.
Harsha Biyani

3

Değişkenin NaN veya None olup olmadığını anlamanın tüm yöntemleri:

Hiçbiri türü

In [1]: from numpy import math

In [2]: a = None
In [3]: not a
Out[3]: True

In [4]: len(a or ()) == 0
Out[4]: True

In [5]: a == None
Out[5]: True

In [6]: a is None
Out[6]: True

In [7]: a != a
Out[7]: False

In [9]: math.isnan(a)
Traceback (most recent call last):
  File "<ipython-input-9-6d4d8c26d370>", line 1, in <module>
    math.isnan(a)
TypeError: a float is required

In [10]: len(a) == 0
Traceback (most recent call last):
  File "<ipython-input-10-65b72372873e>", line 1, in <module>
    len(a) == 0
TypeError: object of type 'NoneType' has no len()

NaN tipi

In [11]: b = float('nan')
In [12]: b
Out[12]: nan

In [13]: not b
Out[13]: False

In [14]: b != b
Out[14]: True

In [15]: math.isnan(b)
Out[15]: True

2

Karışık veri türleri listesinden NaN (kayan nokta) öğelerini kaldırma

Bir yinelemede karışık tipleriniz varsa, burada numpy kullanmayan bir çözüm var:

from math import isnan

Z = ['a','b', float('NaN'), 'd', float('1.1024')]

[x for x in Z if not (
                      type(x) == float # let's drop all float values…
                      and isnan(x) # … but only if they are nan
                      )]
['a', 'b', 'd', 1.1024]

Kısa devre değerlendirmesi, sağ tarafı değerlendirmek zorunda kalmadan hızlı bir şekilde değerlendirildiği isnangibi 'şamandıra' tipi olmayan değerlerde çağrılmayacağı anlamına gelir .False and (…)False


1

Python 3.6'da x math.isnan (x) ve np.isnan (x) dize değerinin kontrol edilmesi bir hata oluşturur. Bu yüzden verilen değerin NaN olup olmadığını kontrol edemiyorum. Aşağıdakiler bu sorunu çözüyor gibi görünüyor

if str(x)=='nan' and type(x)!='str':
    print ('NaN')
else:
    print ('non NaN')

1

Görünüşe göre kendisinin eşit olup olmadığını kontrol etmek

x!=x

en hızlısıdır.

import pandas as pd 
import numpy as np 
import math 

x = float('nan')

%timeit x!=x                                                                                                                                                                                                                        
44.8 ns ± 0.152 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit math.isnan(x)                                                                                                                                                                                                               
94.2 ns ± 0.955 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit pd.isna(x) 
281 ns ± 5.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.isnan(x)                                                                                                                                                                                                                 
1.38 µs ± 15.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

0

Nan tipi şamandıra için

>>> import pandas as pd
>>> value = float(nan)
>>> type(value)
>>> <class 'float'>
>>> pd.isnull(value)
True
>>>
>>> value = 'nan'
>>> type(value)
>>> <class 'str'>
>>> pd.isnull(value)
False

-5

panda dizeleri için pd.isnull almak:

if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):

NLTK için özellik çıkarma işlevi

def act_features(atext):
features = {}
if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):
    if word not in default_stopwords:
      features['cont({})'.format(word.lower())]=True
return features

Bu indirgeme ne olacak?
Max Kleiner

isnull sadece NaN değerleri için değil true değerini döndürür.
Boris
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.