Sel kosong adalah masalah data yang paling sering kita temui, dan pandas menanganinya dengan satu penanda khusus bernama NaN. Penanda ini berperilaku tidak biasa dibanding nilai biasa: perbandingannya selalu gagal dan operasi aritmetika ikut tercemar. Chapter ini membahas apa itu missing values, bagaimana None Python berubah menjadi NaN, serta bagaimana pandas 3.0 menandai kekosongan pada tiap tipe data. Pemahaman ini menjadi fondasi sebelum kita menghitung dan membersihkan nilai kosong pada Chapter-Chapter berikutnya.
NaN: Penanda Kekosongan dari NumPy #
NaN adalah singkatan dari Not a Number, nilai khusus dari standar floating-point IEEE 754 yang dipinjam pandas dari NumPy. Meskipun namanya “bukan angka”, NaN bertipe float64, sehingga kehadirannya membuat kolom bilangan bulat berubah menjadi float64. Nilai ini bukan string "NaN" dan bukan None milik Python; ketiganya terlihat serupa di layar tetapi identitasnya berbeda. Ketika kita menulis None di dalam data numerik, pandas mengonversinya menjadi NaN, dan itulah bentuk yang tersimpan di memori.
None dan np.nan di Dua Tipe Kolom #
Skrip berikut membuat dua Series dari dataset pesanan yang sama: satu berisi angka umur dan satu berisi teks nama_pelanggan. Keduanya memuat satu nilai kosong, lalu kita bandingkan cara pandas 3.0 menyimpannya. Perhatikan pula hasil dua perbandingan di bagian bawah output, yang memperlihatkan sifat aneh NaN:
import numpy as np
import pandas as pd
umur = pd.Series([29, 34, None, 41])
print(umur)
print("dtype:", umur.dtype)
nama = pd.Series(["Budi", None, "Dewi"])
print(nama)
print("dtype:", nama.dtype)
print("np.nan == np.nan ->", np.nan == np.nan)
print("pd.isna(np.nan) ->", pd.isna(np.nan))
print("Sel kosong umur :", umur.isna().sum())
print("Jumlah umur (sum):", umur.sum())Output yang Dihasilkan:
0 29.0
1 34.0
2 NaN
3 41.0
dtype: float64
dtype: float64
0 Budi
1 NaN
2 Dewi
dtype: str
dtype: str
np.nan == np.nan -> False
pd.isna(np.nan) -> True
Sel kosong umur : 1
Jumlah umur (sum): 104.0Mari kita telaah apa yang terjadi pada kode di atas:
- Baris 4 (
umur = pd.Series([29, 34, None, 41])): kita membuat Series angka dengan satuNonedi tengah. - Baris 5-6: pandas menampilkan nilai kosong sebagai
NaNdan melaporkan dtypefloat64; angka bulat 29 menjadi 29.0 karena seluruh kolom mengikuti tipeNaN. - Baris 8-10: Series teks dengan satu
Nonemenghasilkan dtypestr, tipe string bawaan pandas 3.0, dan kekosongan tetap tampil sebagaiNaN, bukanpd.NA. - Baris 12-13 (
np.nan == np.nan): perbandinganNaNdenganNaNmenghasilkanFalsesesuai aturan IEEE 754; satu-satunya cara mengujinya adalahpd.isna(). - Baris 14-15:
isna().sum()menghitung satu sel kosong, sedangkanumur.sum()tetap menghasilkan104.0karena pandas melewatiNaNsaat menjumlahkan.
Perilaku Kekosongan pada Tiap Tipe Data #
Satu penanda tidak berlaku seragam untuk semua tipe. Tabel berikut merangkum penanda kekosongan yang dipakai pandas 3.0:
| Tipe data | Penanda kosong | Contoh pada dataset pesanan |
|---|---|---|
float64 | NaN | Kolom umur dan total_belanja |
str | NaN | Sel kota milik PSC-106 |
Int64 (nullable) | <NA> (pd.NA) | Bilangan bulat dengan sel kosong, dibahas pada Chapter Memperbaiki Tipe Data |
datetime64 | NaT | Tanggal kosong |
Perubahan paling penting di pandas 3.0 ada pada kolom teks. Sejak dtype str menjadi bawaan, nilai kosong pada kolom teks tetap NaN, bukan pd.NA; rincian migrasinya dijelaskan pada panduan pembaruan string pandas 3.0
. Konsekuensinya sederhana bagi kita: satu fungsi pd.isna() mampu mendeteksi kekosongan pada hampir semua tipe tanpa perkecualian. Panduan resmi Working with missing data
merangkum seluruh perilaku ini beserta tabel konversinya.
Sekarang kita tahu bahwa kekosongan tersimpan sebagai NaN, NaT, atau pd.NA tergantung tipe kolom, dan bahwa perbandingan langsung tidak pernah berhasil. Pertanyaan berikutnya lebih praktis: berapa banyak sel kosong di setiap kolom, dan baris mana saja yang terdampak? Chapter Mendeteksi Nilai Kosong menjawabnya dengan fungsi pandas.isna
beserta kebalikannya, notna().