Apa perbedaan antara NaN dan None?

97

Saya membaca dua kolom file csv menggunakan panda readcsv()dan kemudian menetapkan nilainya ke kamus. Kolom berisi rangkaian angka dan huruf. Terkadang ada kasus di mana sel kosong. Menurut pendapat saya, nilai yang dibaca untuk entri kamus itu harus Nonetetapi nanditetapkan. Tentunya Nonelebih deskriptif dari sel kosong karena memiliki nilai null, sedangkan nanhanya mengatakan bahwa nilai yang dibaca bukanlah angka.

Apakah pemahaman saya benar, apa perbedaan antara Nonedan nan? Mengapa nanditugaskan alih-alih None?

Juga, kamus saya memeriksa apakah ada sel kosong yang telah digunakan numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Tetapi ini memberi saya kesalahan yang mengatakan bahwa saya tidak dapat menggunakan pemeriksaan ini v. Saya kira itu karena variabel integer atau float, bukan string yang dimaksudkan untuk digunakan. Jika ini benar, bagaimana cara memeriksa vkotak / "sel kosong" nan?

pengguna1083734
sumber
Teks qwertyitu bukan angka.
Robert Harvey
1
@RobertHarvey Saya tahu, jadi pasti Noneakan menjadi deskripsi yang lebih baik tentang nilai sel kosong.
pengguna1083734

Jawaban:

110

NaN digunakan sebagai placeholder untuk data yang hilang secara konsisten di panda , konsistensinya bagus. Saya biasanya membaca / menerjemahkan NaN sebagai "hilang" . Lihat juga bagian 'bekerja dengan data yang hilang' di dokumen.

Kami menulis dalam 'pilihan representasi NA' dokumen :

Setelah bertahun-tahun penggunaan produksi [NaN] telah terbukti, setidaknya menurut pendapat saya, sebagai keputusan terbaik mengingat keadaan di NumPy dan Python secara umum. Nilai khusus NaN (Not-A-Number) digunakan di mana - mana sebagai nilai NA, dan ada fungsi API isnulldan notnullyang dapat digunakan di seluruh dtypes untuk mendeteksi nilai NA.
...
Jadi, saya telah memilih pendekatan Pythonic "kepraktisan mengalahkan kemurnian" dan memperdagangkan kemampuan integer NA untuk pendekatan yang lebih sederhana dalam menggunakan nilai khusus dalam float dan array objek untuk menunjukkan NA, dan mempromosikan array integer menjadi mengambang ketika NAs harus diperkenalkan.

Catatan: "Gotcha" bahwa Seri bilangan bulat yang berisi data yang hilang di-upcast menjadi float .

Menurut pendapat saya, alasan utama untuk menggunakan NaN (over None) adalah karena NaN dapat disimpan dengan dtype float64 numpy, daripada dtype objek yang kurang efisien, lihat promosi tipe NA .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff berkomentar (di bawah) tentang ini:

np.nanmemungkinkan untuk operasi vektor; its a float value, sedangkan None, menurut definisi, memaksa tipe objek, yang pada dasarnya menonaktifkan semua efisiensi di numpy.

Jadi ulangi 3 kali dengan cepat: object == bad, float == good

Mengatakan itu, banyak operasi mungkin masih bekerja dengan baik dengan None vs NaN (tetapi mungkin tidak didukung, yaitu terkadang memberikan hasil yang mengejutkan ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Untuk menjawab pertanyaan kedua:
Anda harus menggunakan pd.isnulldan pd.notnulluntuk menguji data yang hilang (NaN).

Andy Hayden
sumber
19
hanya menambahkan 2c di sini .... np.nanmemungkinkan untuk operasi vektor; ini adalah nilai float, sedangkan Nonemenurut definisi objectjenis gaya , dan pada dasarnya menonaktifkan semua efisiensi di numpy, jadi ulangi 3 kali dengan cepat:object==bad, float==good
Jeff
1
Apakah <NA>juga np.nan?
Gathide
18

NaNdapat digunakan sebagai nilai numerik pada operasi matematika, sementara Nonetidak bisa (atau setidaknya tidak boleh).

NaNadalah nilai numerik, seperti yang didefinisikan dalam standar floating-point IEEE 754 . Noneadalah jenis Python internal ( NoneType) dan akan lebih seperti "tidak ada" atau "kosong" daripada "tidak valid secara numerik" dalam konteks ini.

"Gejala" utama dari hal itu adalah, jika Anda melakukan, katakanlah, rata-rata atau jumlah pada larik yang berisi NaN, bahkan satu, Anda mendapatkan NaN sebagai hasilnya ...

Di sisi lain, Anda tidak dapat melakukan operasi matematika menggunakan Noneoperand.

Jadi, bergantung pada kasusnya, Anda dapat menggunakan Nonesebagai cara untuk memberi tahu algoritme Anda agar tidak mempertimbangkan nilai yang tidak valid atau tidak ada pada komputasi. Itu berarti algoritme harus menguji setiap nilai untuk melihat apakah benar None.

Numpy memiliki beberapa fungsi untuk menghindari nilai NaN mencemari hasil Anda, seperti nansumdan nan_to_nummisalnya.

heltonbiker
sumber
Saya setuju dengan Anda bahwa Tidak Ada harus digunakan untuk entri yang tidak ada, jadi mengapa df=pd.readcsv('file.csv')memberi saya NaNnilai untuk sel kosong dan tidak None? Sejauh yang saya tahu, pd.DataFrames tidak eksklusif untuk angka.
pengguna1083734
Ya, itu mungkin pilihan desain. Saya kira DataFrames dan Series memiliki a dtype, jadi nilai yang tidak valid dtype=floatharus diwakili oleh nilai numerik, yang mana NaNdan Nonebukan ( Nonedari NoneType).
heltonbiker
Juga, banyak metode Pandas memiliki naargumen, yang memungkinkan Anda memutuskan nilai mana yang akan Anda gunakan untuk mengganti nilai yang tidak tersedia
heltonbiker
Ok terima kasih. Jadi saya sebenarnya tidak membaca angka ke dalam DataFrame saya, tetapi rangkaian angka dan huruf. Jenis pemeriksaan apa yang harus saya gunakan untuk mendeteksi sel kosong? Sebuah cek seperti; jika dtype == float: ??
pengguna1083734
Mungkin mengeposkan sampel data CSV Anda akan membantu. Saya bisa membayangkan bahwa, jika ada string, maka dtype akan menjadi string untuk seluruh kolom (Seri). Tetapi mungkin jika tidak setiap baris memiliki jumlah kolom yang sama, Anda akan mendapatkan data yang tidak tersedia. Saya pikir Anda harus memeriksanya.
heltonbiker
3

Fungsi ini isnan()memeriksa untuk melihat apakah ada sesuatu yang "Bukan Angka" dan akan mengembalikan apakah variabel adalah angka atau tidak, misalnya isnan(2)akan mengembalikan salah

Pengembalian bersyarat myVar is not Noneapakah variabel ditentukan atau tidak

Array numpy Anda menggunakan isnan()karena dimaksudkan sebagai larik angka dan menginisialisasi semua elemen larik ke NaNelemen ini dianggap "kosong"

Stephan
sumber
1
Saya pikir isnan(2)akan kembali False, karena 2 bukan NaN.
heltonbiker
Juga, numpy.emptytidak menginisialisasi nilai array ke NaN. Itu sama sekali tidak menginisialisasi nilai sama sekali.
heltonbiker
5
Pemeriksaan yang tepat untuk None-ness adalah myVar is not None, bukan myVar != None.
Jaime
3
Catatan itu np.isnan()tidak diimplementasikan untuk variabel string, jadi jika Anda meneruskannya string itu akan macet. Lebih baik menggunakan pd.isnullyang bekerja dengan string.
Michael
-1

Berikut perbedaannya:

  • nan milik kelas float
  • None milik kelas NoneType

Saya menemukan artikel di bawah ini sangat membantu: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31

eswara amirthan s
sumber
Meskipun tautan ini mungkin menjawab pertanyaan, lebih baik menyertakan bagian penting dari jawaban di sini dan menyediakan tautan untuk referensi. Jawaban link saja bisa menjadi tidak valid jika halaman tertaut berubah. - Dari Ulasan
A. Kootstra
@ A.Kootra Saya mengerti
eswara amirthan s
-3

NaNstants untuk BUKAN nomor .
Nonemungkin berdiri untuk apapun .

diegoaguilar
sumber