Menghitung lebih dulu, membersihkan kemudian — prinsip itu berlaku untuk nilai kosong. Sebelum memutuskan menghapus atau mengisi, kita perlu jawaban pasti atas dua pertanyaan: berapa banyak sel kosong di setiap kolom, dan baris mana saja yang terdampak. Chapter ini melatih dua fungsi pendeteksi utama pandas, isna() dan notna(), lalu menggabungkannya dengan sum() serta penyaringan boolean dari Section sebelumnya. Dataset pesanan kotor tetap kita pakai agar hasilnya mudah dicocokkan dengan Chapter-Chapter sebelumnya.
Peta Boolean Sel Kosong #
isna() mengembalikan struktur data baru dengan bentuk sama seperti aslinya, tetapi isinya True untuk sel kosong dan False untuk sel terisi. Kebalikannya, notna() memberi True untuk sel yang terisi. Karena hasilnya boolean, kita bisa membacanya sebagai peta lokasi kekosongan pada seluruh tabel. Mari kita jalankan keduanya pada dataset pesanan:
import pandas as pd
pesanan = pd.DataFrame(
{
"id_pesanan": [
"PSC-101", "PSC-102", "PSC-103", "PSC-104", "PSC-105",
"PSC-106", "PSC-101", "PSC-102", "PSC-103", "PSC-107",
],
"nama_pelanggan": [
"Budi", "Siti", "Dewi", "Andi", "Rina",
"Tono", "Budi", "Siti", "Dewi", "Sari",
],
"kota": [
"Jakarta", "Bandung", "Surabaya", "JAKARTA", "Bandung",
None, "Jakarta", "Bandung", "Surabaya", "Medan",
],
"umur": [29, 34, None, 41, 27, 38, 29, 34, None, 45],
"total_belanja": [
250000, 480000, 150000, None, 320000,
275000, 250000, 480000, 165000, 190000,
],
}
)
print(pesanan.isna())
print()
print("Sel kosong per kolom:")
print(pesanan.isna().sum())
print("Total sel kosong :", pesanan.isna().sum().sum())
print()
print("Baris dengan kota kosong:")
print(pesanan[pesanan["kota"].isna()])
print()
print("Sel terisi per kolom (notna):")
print(pesanan.notna().sum())Output yang Dihasilkan:
id_pesanan nama_pelanggan kota umur total_belanja
0 False False False False False
1 False False False False False
2 False False False True False
3 False False False False True
4 False False False False False
5 False False True False False
6 False False False False False
7 False False False False False
8 False False False True False
9 False False False False False
Sel kosong per kolom:
id_pesanan 0
nama_pelanggan 0
kota 1
umur 2
total_belanja 1
dtype: int64
Total sel kosong : 4
Baris dengan kota kosong:
id_pesanan nama_pelanggan kota umur total_belanja
5 PSC-106 Tono NaN 38.0 275000.0
Sel terisi per kolom (notna):
id_pesanan 10
nama_pelanggan 10
kota 9
umur 8
total_belanja 9
dtype: int64Mari kita telaah peran setiap bagian skrip di atas:
- Baris 25 (
print(pesanan.isna())): matriks boolean berukuran 10x5; hanya 4 sel berisiTrue, tepat pada lokasi kekosongan yang kita tanam. - Baris 28 (
pesanan.isna().sum()):sum()menjumlahkan kolom demi kolom;Truedihitung 1 danFalsedihitung 0, sehingga hasilnya banyaknya sel kosong per kolom. - Baris 29 (
pesanan.isna().sum().sum()): penjumlahan kedua meratakan seluruh matriks menjadi satu angka, yaitu 4 sel kosong. - Baris 31-32 (
pesanan[pesanan["kota"].isna()]): Series boolean dipakai sebagai mask sehingga hanya baris PSC-106 milik Tono yang tampil. - Baris 35 (
pesanan.notna().sum()): kebalikanisna(); kolomumurterisi 8 dari 10 sel.
Dari Hitungan ke Persentase #
Angka absolut berubah makna ketika ukuran tabel berbeda; 4 sel kosong pada tabel 50 sel jauh lebih serius daripada 4 sel kosong pada tabel 5 juta sel. Untuk membandingkan antar kolom maupun antar file, gunakan rata-rata: pesanan.isna().mean() * 100 menghasilkan persentase kekosongan per kolom, dan pada data kita kolom umur kehilangan 20 persen. Kombinasi isna().mean() sering muncul di laporan kualitas data industri karena ringkas dan langsung terbaca. Panduan Working with missing data
memuat pola serupa sebagai titik awal investigasi.
Menyaring Baris yang Terdampak #
Mask dari isna() bisa langsung dimasukkan ke kurung siku DataFrame, persis pola filtering boolean yang kita pelajari pada Section Indexing dan Seleksi Data. Bila baris yang dicari kosong pada salah satu dari dua kolom, gabungkan dua mask dengan operator | dan tanda kurung, misalnya pesanan[pesanan["kota"].isna() | pesanan["umur"].isna()] yang menampilkan 3 baris pada data kita. Sebaliknya, untuk melihat baris yang benar-benar lengkap, gunakan pesanan[pesanan.notna().all(axis=1)]; jumlahnya sama persis dengan baris yang tersisa setelah dropna(), yang kita bedah pada Chapter berikutnya.
Kini kita mampu memetakan kekosongan dengan presisi: berapa banyak, di kolom apa, dan di baris mana. Fungsi pandas.DataFrame.isna
beserta saudaranya pandas.DataFrame.notna
juga berlaku pada Series dengan perilaku yang sama. Tersisa satu keputusan strategi: menghapus baris yang kosong atau mengisinya dengan nilai pengganti. Chapter Menghapus Nilai Kosong membahas jalur pertama melalui dropna() beserta parameter how dan subset.