Belajar Data Analyst - Data Cleaning & Preparation
Episode 7 of 28

Belajar Data Analyst - Data Cleaning & Preparation

Episode ini membahas pekerjaan yang memakan 60-80% waktu analis: data cleaning. Kalian akan menangani missing values, duplikat, outlier, tipe data yang salah, dan normalisasi dengan pandas, ditutup praktik membersihkan dataset kotor yang realistis

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 6 kalian mulai eksplorasi data dengan pandas. Sekarang mari hadapi kenyataan yang tidak nyaman: data di dunia nyata itu kotor. Kolom kosong, duplikat, format tanggal yang berantakan, harga bertuliskan "Rp 150.000", dan outlier yang mencurigakan. Statistik yang bagus tidak akan menyelamatkan analisis yang dibangun di atas data kotor — prinsip yang dikenal sebagai garbage in, garbage out.

Episode ini membahas lima masalah data yang paling umum dan cara menanganinya dengan pandas. Tujuannya bukan sekadar hafal fungsi, melainkan memahami kapan harus membersihkan, apa konsekuensi tiap keputusan, dan kapan harus menahan diri — karena cleaning yang berlebihan bisa sama berbahayanya dengan tidak membersihkan sama sekali.

Dataset Kotor Contoh

Kita bekerja dengan data pembelian yang sengaja dibuat bermasalah, disimpan sebagai purchase_raw.csv:

text
id,user_id,product,harga,quantity,tanggal
1,u001,Laptop,"Rp 15.000.000",2,2025-11-01
2,u001,Laptop,"Rp 15.000.000",2,2025-11-01
3,u002,Keyboard,"Rp 500.000",1,01/11/2025
4,,Mouse,"",0,
5,u003,Monitor,"Rp 3.000.000",-1,2025-11-10
6,u004,Keyboard,500000,1,2025-11-12

Perhatikan masalahnya: harga bercampur teks dan angka, ada baris tanpa user, harga kosong, quantity negatif, tanggal dengan format berbeda, dan baris ganda. Tugas kalian: jadikan ini tabel yang bisa dianalisis.

1. Tipe Data: Normalisasi Sejak Awal

PythonCek tipe data asli
import pandas as pd
 
df = pd.read_csv("purchase_raw.csv")
print(df.dtypes)

harga akan terbaca sebagai object (karena ada "Rp 15.000.000") dan tanggal sebagai object (format campuran). Bersihkan angka dulu, baru ubah tipenya:

PythonBersihkan harga dan konversi tipe
import re
 
def bersihkan_harga(v):
    if isinstance(v, str):
        v = v.replace("Rp", "").replace(".", "").strip()
    try:
        return float(v)
    except ValueError:
        return float("nan")
 
df["harga"] = df["harga"].apply(bersihkan_harga)
df["tanggal"] = pd.to_datetime(df["tanggal"], errors="coerce")
df["harga"] = df["harga"].astype("float")

Aturan emas: selalu tetapkan tipe data yang benar sebelum analisis — tanggal jadi datetime, angka jadi float/int, kategori jadi category. Query dan agregasi kemudian berjalan konsisten.

Important

Setiap keputusan cleaning HARUS bisa dijelaskan. Simpan pipeline cleaning sebagai script (bukan hanya diingat), karena stakeholder pasti bertanya "kenapa angka di laporan saya berbeda dari sistem?" Jawaban yang benar dimulai dari data mentah yang jelas prosesnya.

2. Missing Values: Jangan Asal Buang

Nilai hilang muncul sebagai NaN. Pilihan penanganannya ada tiga, tergantung konteks:

StrategiKapan dipakaiRisiko
Buang baris (dropna)Nilai hilang sedikit, baris tak pentingKehilangan informasi
Isi nilai (fillna)Nilai hilang acak, ada estimator wajarMemasukkan asumsi
Biarkan / tandaiNilai hilang punya arti (misal "tidak pernah order")Kompleksitas model
PythonInspeksi dan penanganan missing values
print(df.isna().sum())
 
df.dropna(subset=["user_id"], inplace=True)   # baris tanpa user: buang
df["harga"].fillna(df["harga"].median(), inplace=True)  # harga kosong: isi median

Isi dengan median (bukan mean) karena distribusi harga skewed. Dan ingat: untuk kolom kategorikal, menandai "tidak diketahui" kadang lebih jujur daripada menebak.

3. Duplikat: Kenali Duplikat Semu

duplicated() mendeteksi baris yang identik. Di contoh kita, baris 1 dan 2 benar-benar identik — itu duplikat sejati:

PythonHapus duplikat
df.drop_duplicates(inplace=True)
print(df.duplicated().sum())

Hati-hati dengan duplikat semu: dua baris "sama" secara visual tetapi punya kolom pembeda (misal transaction_id). Sebelum drop_duplicates, putuskan subset kolom mana yang mendefinisikan keunikan — misal subset=["user_id", "product", "tanggal"].

4. Outlier: Investigasi, Bukan Otomatis Buang

Outlier adalah nilai yang jauh dari mayoritas data. Dua pertanyaan wajib sebelum bertindak: apakah ini error data atau fakta nyata? dan apakah ia mengubah kesimpulan kita?

PythonDeteksi outlier dengan IQR
Q1 = df["harga"].quantile(0.25)
Q3 = df["harga"].quantile(0.75)
IQR = Q3 - Q1
batas_bawah = Q1 - 1.5 * IQR
batas_atas = Q3 + 1.5 * IQR
print(df[(df["harga"] < batas_bawah) | (df["harga"] > batas_atas)])

Di dataset kita, quantity bernilai negatif jelas error (pasti 1, atau baris yang salah). Tapi harga laptop yang 5x median belum tentu error — bisa jadi itu segmen enterprise. Jangan pernah menghapus outlier otomatis; periksa satu per satu, dokumentasikan keputusan.

PythonPerbaiki quantity negatif
df.loc[df["quantity"] < 0, "quantity"] = 1

5. Normalisasi: Konsistensi Kategorikal

Normalisasi di sini bukan soal statistik, melainkan konsistensi nilai kategorikal: "Jakarta" vs "jakarta" vs "JKT" dianggap tiga nilai berbeda oleh komputer.

PythonStandarkan nilai kategorikal
df["product"] = df["product"].str.strip().str.title()
print(df["product"].value_counts())

Kebiasaan baik: simpan data dictionary sederhana — tabel yang mendokumentasikan tiap kolom, tipe, dan transformasi yang diterapkan. Ini langkah kecil yang membedakan analis profesional dari amatir.

Pipeline Cleaning Lengkap

Rangkum semuanya dalam satu fungsi agar bisa dipakai ulang:

PythonPipeline cleaning satu paket
def clean_purchase(df):
    df = df.copy()
    df["harga"] = df["harga"].apply(bersihkan_harga)
    df["tanggal"] = pd.to_datetime(df["tanggal"], errors="coerce")
    df = df.dropna(subset=["user_id"])
    df["harga"] = df["harga"].fillna(df["harga"].median())
    df["quantity"] = df["quantity"].clip(lower=1)
    df["product"] = df["product"].str.strip().str.title()
    df = df.drop_duplicates(subset=["user_id", "product", "tanggal"])
    return df
 
bersih = clean_purchase(pd.read_csv("purchase_raw.csv"))
bersih.to_csv("purchase_clean.csv", index=False)

Satu fungsi, dapat diulang, dapat dijelaskan. Ini pola yang akan kalian bawa sampai ke episode 18 (data quality testing).

Kesalahan Umum

  • dropna() tanpa berpikir. Jumlah baris mengecil diam-diam; cek berapa baris yang hilang dan mengapa.
  • Mengisi semua NaN dengan 0. Nol bukan berarti "tidak ada data"; ia punya makna sendiri dan merusak rata-rata.
  • Menghapus outlier otomatis dengan IQR. Wajib investigasi; laptop enterprise bukan data error.
  • Tidak menyimpan pipeline. Cleaning tanpa script = analisis yang tidak reproducible.

Penutup

Inti yang harus dibawa pulang:

  • Perbaiki tipe data dulu (datetime, float), lalu tangani missing, duplikat, outlier, dan konsistensi.
  • Missing values: buang, isi, atau biarkan — sesuai konteks dan terdokumentasi.
  • Duplikat semu butuh definisi subset kolom yang jelas.
  • Outlier diinvestigasi, bukan dihapus otomatis.
  • Bungkus cleaning dalam satu pipeline yang reusable dan reproducible.

Di episode 8 selanjutnya kita akan menganalisis data yang sudah bersih — EDA & feature understanding: analisis univariat, bivariat, korelasi, dan distribusi variabel, plus menyusun laporan EDA singkat. Data kalian sekarang bersih; saatnya membiarkan data berbicara!

Belajar Data Analyst - Data Cleaning & Preparation | Belajar Data Analyst