TL;DR
df.fillna() adalah metode pandas buat ngisi missing value alias NaN dengan nilai pengganti, misalnya df.fillna(0) buat ganti semua kosong jadi nol. Kamu bisa isi pakai angka tetap, rata-rata atau median kolom, atau ambil nilai dari baris sebelumnya pakai ffill dan sesudahnya pakai bfill. Buat kolom yang beda-beda, oper dict biar tiap kolom punya nilai pengisi sendiri. Pilih fillna kalau baris kosong masih berguna, pilih dropna kalau lebih baik dibuang.
df.fillna() adalah metode pandas buat ngisi missing value, atau nilai kosong yang muncul sebagai NaN, dengan nilai pengganti. Contoh paling dasar: df.fillna(0) ngubah semua sel kosong jadi nol.
Missing value itu masalah nyata. Rata-rata jadi salah, chart bolong, dan beberapa model langsung error kalau ada NaN. fillna nutup lubang itu dengan nilai yang masuk akal.
Di bawah ini aku bahas cara isi pakai angka, pakai rata-rata, pakai nilai tetangga lewat ffill, sampai isi beda-beda tiap kolom. Plus kapan lebih baik dibuang aja. Semua pakai dataset toko_berkah.
pandas fillna adalah metode DataFrame.fillna() atau Series.fillna() yang ngeganti nilai NaN dengan nilai yang kamu tentuin. NaN itu penanda data hilang di pandas, muncul waktu sel kosong, hasil pembagian gagal, atau data nggak kebaca. fillna balikin DataFrame baru dengan lubang-lubang itu terisi, sementara data aslinya nggak berubah kecuali kamu simpan hasilnya.
Kalau kamu belum kenal betul apa itu NaN dan kenapa muncul, ada penjelasannya di glosarium NaN.
Bentuk paling sederhana: oper satu nilai, semua NaN keganti.
import pandas as pd
df = pd.read_csv("transaksi.csv")
# ganti semua kosong jadi 0
df = df.fillna(0)
Buat isi satu kolom aja, panggil di kolomnya:
df["diskon"] = df["diskon"].fillna(0)
Ini yang paling sering kepakai. Kolom diskon yang kosong berarti nggak ada diskon, jadi diisi 0 itu bener secara logika. Tapi hati-hati, nggak semua kolom cocok diisi 0. Kolom harga yang diisi 0 malah bikin rata-rata anjlok.
fillna balikin DataFrame baru. Simpan ke variabel yang sama kayak contoh di atas, atau data aslinya nggak berubah.
Buat kolom angka, ngisi pakai rata-rata atau median lebih masuk akal daripada 0. Nilai pengisinya ngikutin sebaran data yang ada.
# isi pakai rata-rata kolom
df["harga"] = df["harga"].fillna(df["harga"].mean())
# isi pakai median kolom
df["harga"] = df["harga"].fillna(df["harga"].median())
Median biasanya lebih aman dari mean. Kalau kolommu punya beberapa nilai ekstrem, mean ketarik sama nilai itu, sementara median tahan banting. Buat data harga atau pendapatan yang sering mencong, aku hampir selalu pilih median.
Buat kolom kategori kayak metode bayar, mean nggak ada artinya. Isi pakai modus, nilai yang paling sering muncul:
df["metode_bayar"] = df["metode_bayar"].fillna(df["metode_bayar"].mode()[0])
mode() balikin Series, jadi ambil elemen pertama pakai [0]. Konsep modus ini sama kayak yang aku bahas di Menghitung Modus di SQL.
Buat data berurut kayak deret waktu, ngisi pakai nilai baris sebelumnya sering paling pas. Ini namanya forward fill.
# isi pakai nilai baris sebelumnya
df["stok"] = df["stok"].ffill()
# isi pakai nilai baris sesudahnya
df["stok"] = df["stok"].bfill()
ffill (forward fill) ngambil nilai terakhir yang nggak kosong lalu nyalin ke bawah. Cocok buat data stok harian: kalau hari ini nggak ada catatan, anggap sama kayak kemarin. bfill (backward fill) kebalikan, ngambil dari baris di bawahnya.
Di pandas versi baru, ffill() dan bfill() jadi metode sendiri. Cara lama pakai fillna(method="ffill") masih jalan tapi udah nggak disarankan. Pakai metode langsungnya biar aman ke depan.
Urutan penting di sini. ffill cuma bener kalau datamu udah diurutin, misalnya per tanggal. Kalau belum, urutin dulu pakai sort_values.
Satu DataFrame sering butuh perlakuan beda tiap kolom. Diskon diisi 0, harga diisi median, kota diisi "Tidak diketahui". Oper dict biar sekali jalan.
nilai_isi = {
"diskon": 0,
"harga": df["harga"].median(),
"kota": "Tidak diketahui"
}
df = df.fillna(nilai_isi)
Tiap key itu nama kolom, tiap value itu nilai pengisinya. Kolom yang nggak disebut di dict dibiarin apa adanya. Cara ini jauh lebih rapi dari nulis fillna satu-satu per kolom, dan niat tiap kolom kelihatan jelas dalam satu tempat.
Nggak semua missing value harus diisi. Kadang lebih jujur dibuang. Ini pertimbanganku.
| Situasi | Pilih |
|---|---|
| Kosong berarti nol (diskon, jumlah) | fillna(0) |
| Data deret waktu berurut | ffill atau bfill |
| Kolom angka buat statistik | fillna median |
| Baris kosong di kolom kunci (ID, tanggal) | dropna |
| Missing-nya banyak banget di satu kolom | drop kolomnya |
Aturan praktisku: kalau ngisi bikin data lebih menyesatkan dari ngebuang, buang. Baris transaksi tanpa ID atau tanpa tanggal nggak bisa diselamatin fillna, mending di-dropna. Cara buang baris kosong ada di Pandas dropna: Menghapus Data Kosong.
Dataset transaksi toko_berkah punya 8.412 baris hasil export dari beberapa cabang. Setelah dicek, ada 3 kolom yang bolong.
diskon: 6.180 baris kosong. Ternyata kosong berarti nggak ada diskon.metode_bayar: 143 baris kosong. Kasir lupa isi.total: 12 baris kosong. Data rusak waktu export.Tiga kolom, tiga perlakuan beda. Diskon diisi 0 soalnya kosong memang berarti nol. Metode bayar diisi modusnya, yaitu QRIS. Total yang kosong nggak bisa ditebak, jadi 12 baris itu aku buang pakai dropna.
df["diskon"] = df["diskon"].fillna(0)
df["metode_bayar"] = df["metode_bayar"].fillna("QRIS")
df = df.dropna(subset=["total"])
Yang menarik: sebelum dibersihin, rata-rata diskon kebaca Rp 8.200, dihitung cuma dari 2.232 baris yang ada isinya. Setelah 6.180 baris kosong diisi 0, rata-rata diskon yang sebenarnya turun jadi Rp 2.170.
Selisihnya besar. Kalau missing value dibiarin, mereka bakal ngira program diskon jauh lebih mahal dari kenyataan. Salah isi missing value bisa langsung nyesatin keputusan. Cara ngisinya harus nyocok sama arti kosongnya.
Isi 0 buat semua kolom. df.fillna(0) ke seluruh DataFrame gampang, tapi salah buat kolom harga atau kategori. Nol di kolom harga bikin statistik ambruk. Tentuin per kolom.
Lupa nyimpan hasilnya. fillna balikin DataFrame baru. Kalau kamu cuma nulis df.fillna(0) tanpa df = di depan, data aslinya nggak berubah.
ffill tanpa ngurutin dulu. Forward fill ngambil dari baris di atas. Kalau data belum diurutin per tanggal, nilai yang kesalin bisa dari waktu yang salah. Urutin dulu.
Ngisi kolom kunci. ID transaksi atau tanggal yang kosong nggak boleh ditebak. Ngisi pakai nilai palsu di kolom kunci lebih bahaya dari ngebuang barisnya.
Ngira 0 sama dengan NaN. Setelah fillna(0), nilai kosong dan nol jadi nggak bisa dibedain. Kalau bedanya penting buat analisis, pikir ulang sebelum ngisi.
fillna(0) ngisi sel kosong dengan nol dan mempertahankan semua baris. dropna ngebuang baris atau kolom yang punya nilai kosong. Pakai fillna kalau nilai kosong itu masih berarti sesuatu, misalnya diskon kosong berarti nggak ada diskon. Pakai dropna kalau baris kosongnya nggak bisa diselamatin, misalnya transaksi tanpa ID atau tanpa tanggal. Salah pilih bisa nyesatin, ngisi nol di tempat yang salah bikin rata-rata jadi ngaco.
Pakai median kalau kolommu punya nilai ekstrem atau sebarannya mencong, misalnya harga atau pendapatan. Median tahan terhadap nilai ekstrem, jadi nilai pengisinya lebih mewakili data biasa. Pakai mean kalau sebarannya kira-kira simetris dan nggak ada ekor yang panjang. Buat sebagian besar data bisnis yang biasanya mencong ke kanan, median lebih aman. Kalau ragu, cek dulu selisih mean dan median, kalau jauh berarti datanya mencong dan median lebih pas.
Oper dict ke fillna, dengan nama kolom sebagai key dan nilai pengisi sebagai value. Contoh: df.fillna({"diskon": 0, "kota": "Tidak diketahui"}). Kolom diskon diisi nol, kolom kota diisi teks, kolom lain dibiarin. Cara ini lebih rapi dari nulis fillna berkali-kali per kolom, dan semua niat pengisian kelihatan jelas dalam satu tempat. Kolom yang nggak disebut di dict nggak keubah sama sekali.
Bisa. ffill ngambil nilai dari baris sebelumnya, jadi kalau baris paling atas udah kosong dari awal, nggak ada nilai sebelumnya buat disalin, dan sel itu tetap NaN. Solusinya kombinasiin: jalanin ffill dulu buat ngisi dari atas, lalu bfill buat nutup sisa kosong di awal, atau sebaliknya. Cara lain, isi sisa NaN yang bandel itu pakai nilai default lewat fillna biasa setelah ffill.
Paling sering gara-gara kamu lupa nyimpan hasilnya. fillna balikin DataFrame baru dan nggak ngubah aslinya, jadi df.fillna(0) doang nggak ngefek. Tulis df = df.fillna(0) biar hasilnya kesimpan. Kemungkinan kedua, sel yang keliatan kosong itu sebenarnya bukan NaN tapi string kosong atau spasi, dan fillna cuma kerja buat NaN asli. Cek dulu pakai df.isna().sum() buat tau ada berapa NaN beneran di tiap kolom.
Ringkasnya:
Buka DataFrame kamu, jalanin df.isna().sum() buat lihat kolom mana yang bolong, lalu tentuin nilai pengisi yang pas per kolom. Lima menit, data kotor kamu jadi siap dianalisis.
Mau lanjut ke sisi ngebuang data kosong? Baca Pandas dropna, dan buat nyaring baris setelah dibersihin, cek Pandas query. Dokumentasi resmi fillna ada di dokumentasi pandas.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Nama toko ketik campur huruf besar-kecil, spasi nyasar di ujung, atau kode produk nempel jadi satu. Accessor .str di pandas ngerapiin semua itu tanpa loop.
Model machine learning cuma ngerti angka, bukan teks kayak merah atau biru. get_dummies ngubah kolom kategori jadi kolom 0/1 dalam satu baris kode.
Cara pakai pandas crosstab buat bikin tabel silang yang menghitung frekuensi antar dua kategori. Contoh analisis kategori produk per kota UMKM.