Bagaimana saya bisa memeriksa nilai NaN?

981

float('nan')menghasilkan Nan (bukan angka). Tetapi bagaimana saya memeriksanya? Seharusnya sangat mudah, tetapi saya tidak dapat menemukannya.

Jack Ha
sumber
20
Untuk beberapa riwayat NaN dalam Python, lihat PEP 754. python.org/dev/peps/pep-0754
Craig McQueen

Jawaban:

1282

math.isnan (x)

Kembali Truejika x adalah NaN (bukan angka), dan Falsesebaliknya.

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True
Gimel
sumber
5
@ charlie-parker: Dalam Python3, math.isnan masih menjadi bagian dari modul matematika. docs.python.org/3/library/math.html#math.isnan . Gunakan numpy.isnan jika Anda mau, jawaban ini hanya saran.
gimel
2
@ SittingBull Lihat docs.python.org/3/library/functions.html#float "Jika argumennya berupa string, harus berisi angka desimal", atau "Infinity" "inf" "nan"
gimel
35
adalah math.isnanlebih suka np.isnan()?
TMWP
34
@TMWP mungkin ... import numpymembutuhkan sekitar 15 MB RAM, sedangkan import mathmembutuhkan sekitar 0,2 MB
petrpulc
9
@TMWP: Jika Anda menggunakan NumPy, numpy.isnanadalah pilihan yang unggul, karena menangani array NumPy. Jika Anda tidak menggunakan NumPy, tidak ada manfaatnya untuk mengambil ketergantungan NumPy dan menghabiskan waktu untuk memuat NumPy hanya untuk cek NaN (tetapi jika Anda menulis jenis kode yang melakukan pengecekan NaN, kemungkinan Anda harus menggunakan NumPy NumPy).
user2357112 mendukung Monica
359

Cara yang biasa untuk menguji NaN adalah untuk melihat apakah itu sama dengan dirinya sendiri:

def isNaN(num):
    return num != num
Chris Jester-Young
sumber
8
Kata peringatan: mengutip komentar Bear di bawah, "Untuk orang-orang yang terjebak dengan python <= 2.5. Nan! = Nan tidak bekerja dengan andal. Sebagai gantinya digunakan numpy." Karena itu, saya belum pernah melihatnya gagal.
mavnn
22
Saya yakin, mengingat operator kelebihan beban, ada banyak cara saya bisa membingungkan fungsi ini. pergi dengan math.isnan ()
djsadinoff
4
Dikatakan dalam spesifikasi 754 yang disebutkan di atas bahwa NaN == NaN harus selalu salah, meskipun tidak selalu diimplementasikan seperti itu. Apakah tidak mungkin ini bagaimana matematika dan / atau numpy memeriksa ini di bawah tenda?
Hari Ganesan
Terima kasih. ini juga 15-20x kali lebih cepat daripada menggunakan np.isnan jika melakukan operasi pada skalar
thomas.mac
5
Meskipun ini berhasil dan, pada tingkat tertentu masuk akal, saya adalah manusia dengan prinsip dan dengan ini saya menyatakan ini sebagai sihir yang dilarang. Silakan gunakan math.isnan sebagai gantinya.
Gonzalo
152

numpy.isnan(number)memberi tahu Anda apakah itu NaNatau tidak.

mavnn
sumber
3
Berfungsi di python versi 2.7 juga.
Michel Keijzers
6
numpy.all(numpy.isnan(data_list))juga berguna jika Anda perlu menentukan apakah semua elemen dalam daftar adalah nan
Jay P.
3
Tidak perlu untuk NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc
6
Ketika jawaban ini ditulis 6 tahun yang lalu, Python 2.5 masih umum digunakan - dan math.isnan bukan bagian dari perpustakaan standar. Sekarang, saya benar-benar berharap itu tidak terjadi di banyak tempat!
mavnn
4
Perhatikan bahwa np.isnan () tidak menangani tipe desimal. Khusus (fungsi banyak numpy) math.isnan () tidak menangani.
comte
55

Berikut adalah tiga cara di mana Anda dapat menguji suatu variabel adalah "NaN" atau tidak.

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)}")

Keluaran

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True
M. Hamza Rajput
sumber
2
pd.isna (nilai) menyelamatkan banyak masalah! bekerja seperti pesona!
abhishake
1
ps.isna()memecahkan masalah saya. Terima kasih!
darthbhyrava
32

di sini adalah jawaban yang bekerja dengan:

  • Implementasi NaN yang menghormati standar IEEE 754
    • yaitu: python ini NaN: float('nan'), numpy.nan...
  • objek lain: string atau apa pun (tidak menimbulkan pengecualian jika ditemui)

A NaN diimplementasikan mengikuti standar, adalah satu-satunya nilai yang perbandingan ketidaksetaraan dengan dirinya sendiri harus dikembalikan Benar:

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

Dan beberapa contoh:

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)}")

Keluaran:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False
x0s
sumber
1
Seri yang saya periksa adalah string dengan nilai yang hilang adalah 'nans' (???) sehingga solusi ini berfungsi jika yang lain gagal.
keithpjolley
numpy.nanadalah floatobjek Python biasa , sama seperti jenis yang dikembalikan oleh float('nan'). Sebagian besar NaN yang Anda temui di NumPy tidak akan menjadi numpy.nanobjek.
user2357112 mendukung Monica
numpy.nanmendefinisikan nilai NaN nya sendiri di perpustakaan yang mendasari di C . Itu tidak membungkus NaN python. Tapi sekarang, mereka berdua mematuhi standar IEEE 754 karena mereka mengandalkan C99 API.
x0s
@ user2357112supportsMonica: Python dan NaN numpy sebenarnya tidak berperilaku dengan cara yang sama: float('nan') is float('nan')(non-unik) dan np.nan is np.nan(unik)
x0s
@ x0s: Itu tidak ada hubungannya dengan NumPy. np.nanadalah objek tertentu, sementara setiap float('nan')panggilan menghasilkan objek baru. Jika Anda melakukannya nan = float('nan'), maka Anda akan mendapatkannya nan is nanjuga. Jika Anda membuat NumPy NaN aktual dengan sesuatu seperti np.float64('nan'), maka Anda akan mendapatkannya np.float64('nan') is not np.float64('nan')juga .
user2357112 mendukung Monica
28

Saya sebenarnya hanya berlari ke ini, tetapi bagi saya itu sedang memeriksa nan, -inf, atau inf. Saya baru saja digunakan

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

Ini berlaku untuk angka, salah untuk nan dan keduanya inf, dan akan memunculkan pengecualian untuk hal-hal seperti string atau tipe lainnya (yang mungkin merupakan hal yang baik). Juga ini tidak mengharuskan mengimpor perpustakaan seperti matematika atau numpy (numpy sangat besar itu menggandakan ukuran aplikasi yang dikompilasi).

DaveTheScientist
sumber
9
math.isfinitetidak diperkenalkan hingga Python 3.2, jadi diberi jawaban dari @DaveTheScientist yang diposting pada 2012 itu tidak sepenuhnya "menciptakan kembali roda" - solusi masih berlaku bagi mereka yang bekerja dengan Python 2.
sudo_coffee
22

math.isnan ()

atau bandingkan nomor itu dengan dirinya sendiri. NaN selalu! = NaN, jika tidak (misalnya jika adalah nomor) perbandingan harus berhasil.

Tomalak
sumber
6
Untuk orang-orang yang terjebak dengan python <= 2.5. Nan! = Nan tidak bekerja dengan andal. Digunakan numpy sebagai gantinya.
Beruang
16

Metode lain jika Anda terjebak pada <2.6, Anda tidak memiliki numpy, dan Anda tidak memiliki dukungan IEEE 754:

def isNaN(x):
    return str(x) == str(1e400*0)
Josh Lee
sumber
12

Yah saya masuk posting ini, karena saya punya beberapa masalah dengan fungsi:

math.isnan()

Ada masalah saat Anda menjalankan kode ini:

a = "hello"
math.isnan(a)

Itu menimbulkan pengecualian. Solusi saya untuk itu adalah melakukan pemeriksaan lagi:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)
Idok
sumber
3
Itu mungkin diturunkan karena isnan () membutuhkan pelampung, bukan string. Tidak ada yang salah dengan fungsinya, dan masalahnya hanya dalam usahanya menggunakannya. (Untuk kasus penggunaan khusus itu solusinya valid, tetapi itu bukan jawaban untuk pertanyaan ini.)
Peter Hansen
6
Hati-hati dengan memeriksa jenis dengan cara ini. Ini tidak akan berfungsi misalnya untuk NaN numpy.float32. Lebih baik menggunakan coba / kecuali konstruksi: def is_nan(x): try: return math.isnan(x) except: return False
Rob
3
NaN tidak berarti bahwa suatu nilai bukan angka yang valid. Ini adalah bagian dari representasi floating point IEEE untuk menentukan bahwa hasil tertentu tidak ditentukan. misal 0 / 0. Karena itu menanyakan apakah "halo" adalah nan tidak ada artinya.
Brice M. Dempsey
2
ini lebih baik karena NaN dapat mendarat di daftar string, int atau float, sehingga berguna check
RAFIQ
Saya harus menerapkan ini untuk menangani kolom string dalam panda.
Cristian Garcia
7

Dengan python <2.6 saya berakhir dengan

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

Ini berfungsi untuk saya dengan python 2.5.1 pada kotak Solaris 5.9 dan dengan python 2.6.5 di Ubuntu 10

Mauro Bianchi
sumber
6
Ini tidak terlalu portabel, karena Windows kadang-kadang menyebutnya-1.#IND
Mike T
5

Saya menerima data dari layanan web yang mengirimkan NaNsebagai string 'Nan'. Tapi mungkin ada jenis string lain di data saya juga, jadi yang sederhana float(value)bisa melempar pengecualian. Saya menggunakan varian berikut dari jawaban yang diterima:

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

Kebutuhan:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True
Mahdi
sumber
1
atautry: int(value)
chwi
@ Chwi jadi apa saran Anda tentang valuemenjadi NaNatau tidak?
Mahdi
Nah, menjadi "bukan angka", apa pun yang tidak bisa dicor ke int saya kira sebenarnya bukan angka, dan pernyataan coba akan gagal? Coba, kembalikan benar, kecuali kembalikan salah.
chwi
@ Chwi Nah, dengan mengambil "bukan angka" secara harfiah, Anda benar, tapi bukan itu intinya di sini. Bahkan, saya mencari persis apa semantiknya NaN(seperti dalam python apa yang bisa Anda dapatkan float('inf') * 0), dan meskipun string 'Halo' bukan angka, tetapi juga bukan NaNkarena NaNmasih merupakan nilai numerik!
Mahdi
@ chwi: Anda benar, jika penanganan pengecualian untuk pengecualian tertentu. Namun dalam jawaban ini, pengecualian umum telah ditangani. Jadi tidak perlu mencentang int(value)Untuk semua pengecualian, Falseakan ditulis.
Harsha Biyani
3

Semua metode untuk mengetahui apakah variabelnya adalah NaN atau Tidak Ada:

Tidak ada tipe

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()

Jenis NaN

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
siberiawolf61
sumber
2

Cara menghapus item NaN (float) dari daftar tipe data campuran

Jika Anda memiliki tipe campuran dalam iterable, berikut adalah solusi yang tidak menggunakan numpy:

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]

Evaluasi hubung-pendek berarti bahwa isnantidak akan dipanggil pada nilai-nilai yang bukan dari tipe 'float', karena False and (…)cepat dievaluasi Falsetanpa harus mengevaluasi sisi kanan.

sleblanc
sumber
1

Dalam Python 3.6 memeriksa nilai string x math.isnan (x) dan np.isnan (x) memunculkan kesalahan. Jadi saya tidak dapat memeriksa apakah nilai yang diberikan NaN atau tidak jika saya tidak tahu sebelumnya itu angka. Berikut ini tampaknya mengatasi masalah ini

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

Tampaknya memeriksa apakah itu sama dengan dirinya sendiri

x!=x

adalah yang tercepat.

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)
Grzegorz
sumber
0

Untuk nan tipe float

>>> 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
J11
sumber
-5

untuk string di panda take pd.isnull:

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

fungsi sebagai ekstraksi fitur untuk NLTK

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
Max Kleiner
sumber
Apa untuk pengurangan ini?
Max Kleiner
isnull mengembalikan nilai true bukan hanya untuk nilai NaN.
Boris