Perolehan dan pembersihan data

Pipeline lengkap perolehan dan pembersihan data untuk dataset proyek yang berantakan.

Daftar isi

Proyek analisis jarang dimulai dari data yang rapi, dan dataset latihan yang bersih biasanya sudah melewati pekerjaan ini tanpa terlihat. Topik ini membahas pipeline pembersihan data, yaitu rangkaian langkah berurutan yang dapat dijalankan ulang, untuk dataset peminjaman perpustakaan yang berantakan. Langkahnya mencakup pemuatan, inspeksi, perbaikan tipe, penanganan duplikat dan nilai yang hilang, validasi, serta penyimpanan hasil bersih. Setelah topik ini, satu berkas mentah yang berantakan berubah menjadi berkas bersih yang siap dianalisis.

Data mentah yang berantakan#

Data contoh berupa catatan peminjaman buku perpustakaan selama satu semester yang diinput oleh beberapa petugas berbeda. Berkas peminjaman-berantakan.csv berikut memuat kekacauan yang paling sering ditemui, yaitu format tanggal yang tidak konsisten, kapitalisasi nama yang acak, satu judul dengan spasi terdepan, satu baris tercatat dua kali, dan satu kolom lama pinjam yang tidak terisi.

csv peminjaman-berantakan.csv
tanggal_pinjam,nama,kategori,judul,lama_hari
2026-08-04,ali,Sains,Ensiklopedia Sains,6
04/08/2026,Budi,Sains,Atlas Tubuh Manusia,7
2026-08-19,budi,Sejarah,Sejarah Kerajaan Nusantara,9
2026-09-02,CITRA,Sains,Eksperimen Sederhana,
2026-09-10,Dewi,Sejarah, Jalur Rempah Nusantara,8
2026-09-23,Dewi,Fiksi,Kumpulan Dongeng Nusantara,12
2026-09-23,Dewi,Fiksi,Kumpulan Dongeng Nusantara,12
2026-10-01,Citra,Fiksi,Petualangan di Pulau Tengah,10
2026-10-14,budi,Fiksi,Cerita Legenda Gunung,11
2026-11-03,Dewi,Sains,Atlas Tubuh Manusia,7
2026-11-12,CITRA,Sains,Eksperimen Sederhana,5
2026-11-20,ali,Sains,Kamus Biologi,10
2026-11-28,Dewi,Sejarah,Sejarah Kerajaan Nusantara,8
2026-12-02,ALI,Fiksi,Cerita Legenda Gunung,8

Inspeksi pertama#

Pembersihan dimulai dari inspeksi, bukan dari perbaikan. Fungsi read_csv memuat berkas mentah ke dalam DataFrame, lalu bentuk, isi, tipe kolom, sel kosong, dan duplikat diperiksa sebelum keputusan apa pun diambil. Blok berikut menjalankan pemeriksaan pembuka itu sekaligus.

python Memuat dan menginspeksi data mentah
import pandas as pd

pinjam = pd.read_csv("peminjaman-berantakan.csv")

print(pinjam.shape)
print()
print(pinjam)
print()
print(pinjam.dtypes)
print()
print("sel kosong per kolom:")
print(pinjam.isna().sum())
print("baris duplikat:", pinjam.duplicated().sum())
text Keluaran
(14, 5)

   tanggal_pinjam   nama kategori                        judul  lama_hari
0      2026-08-04    ali    Sains           Ensiklopedia Sains        6.0
1      04/08/2026   Budi    Sains          Atlas Tubuh Manusia        7.0
2      2026-08-19   budi  Sejarah   Sejarah Kerajaan Nusantara        9.0
3      2026-09-02  CITRA    Sains         Eksperimen Sederhana        NaN
4      2026-09-10   Dewi  Sejarah       Jalur Rempah Nusantara        8.0
5      2026-09-23   Dewi    Fiksi   Kumpulan Dongeng Nusantara       12.0
6      2026-09-23   Dewi    Fiksi   Kumpulan Dongeng Nusantara       12.0
7      2026-10-01  Citra    Fiksi  Petualangan di Pulau Tengah       10.0
8      2026-10-14   budi    Fiksi        Cerita Legenda Gunung       11.0
9      2026-11-03   Dewi    Sains          Atlas Tubuh Manusia        7.0
10     2026-11-12  CITRA    Sains         Eksperimen Sederhana        5.0
11     2026-11-20    ali    Sains                Kamus Biologi       10.0
12     2026-11-28   Dewi  Sejarah   Sejarah Kerajaan Nusantara        8.0
13     2026-12-02    ALI    Fiksi        Cerita Legenda Gunung        8.0

tanggal_pinjam     object
nama               object
kategori           object
judul              object
lama_hari         float64
dtype: object

sel kosong per kolom:
tanggal_pinjam    0
nama              0
kategori          0
judul             0
lama_hari         1
dtype: int64
baris duplikat: 1

Keluarannya menunjukkan 14 baris dengan 5 kolom, dan setiap kekacauan yang disebut sebelumnya kini tampak pada tabelnya. Kolom tanggal_pinjam terbaca sebagai teks biasa karena formatnya campuran, sedangkan kolom lama_hari berubah menjadi bilangan desimal karena sel kosong terbaca sebagai Not a Number (NaN), yaitu penanda sel kosong pada kolom numerik. Penghitung duplicated().sum() menemukan satu baris duplikat, sehingga daftar pekerjaan pembersihan sudah lengkap sebelum langkah perbaikan pertama dijalankan.

Memperbaiki tipe tanggal dan teks#

Langkah pertama memperbaiki tipe dan teks yang salah format. Tanggal campuran diubah menjadi tipe tanggal dengan to_datetime dan argumen format="mixed", yaitu mode yang mengurai setiap nilai dengan formatnya sendiri, sedangkan dayfirst=True menegaskan bahwa tanggal bergaya 04/08/2026 berarti hari lebih dahulu. Nama siswa dirapikan dengan str.strip().str.title(), dan spasi tepi judul dihilangkan dengan str.strip().

python Memperbaiki tipe tanggal dan merapikan teks
import pandas as pd

pinjam = pd.read_csv("peminjaman-berantakan.csv")

print("judul dengan spasi terdepan:", pinjam["judul"].str.startswith(" ").sum())
pinjam["tanggal_pinjam"] = pd.to_datetime(
    pinjam["tanggal_pinjam"], format="mixed", dayfirst=True
)
pinjam["nama"] = pinjam["nama"].str.strip().str.title()
pinjam["judul"] = pinjam["judul"].str.strip()

print("judul dengan spasi terdepan:", pinjam["judul"].str.startswith(" ").sum())
print()
print(pinjam.dtypes)
print()
print(pinjam.head(6))
text Keluaran
judul dengan spasi terdepan: 1
judul dengan spasi terdepan: 0

tanggal_pinjam    datetime64[ns]
nama                      object
kategori                  object
judul                     object
lama_hari                float64
dtype: object

  tanggal_pinjam   nama kategori                       judul  lama_hari
0     2026-08-04    Ali    Sains          Ensiklopedia Sains        6.0
1     2026-08-04   Budi    Sains         Atlas Tubuh Manusia        7.0
2     2026-08-19   Budi  Sejarah  Sejarah Kerajaan Nusantara        9.0
3     2026-09-02  Citra    Sains        Eksperimen Sederhana        NaN
4     2026-09-10   Dewi  Sejarah      Jalur Rempah Nusantara        8.0
5     2026-09-23   Dewi    Fiksi  Kumpulan Dongeng Nusantara       12.0

Keluarannya menunjukkan kolom tanggal_pinjam kini bertipe datetime64, baris 04/08/2026 terurai menjadi 2026-08-04, dan nama seperti ali serta CITRA menjadi Ali dan Citra. Penghitung spasi terdepan turun dari satu menjadi nol, sehingga judul yang semula tersembunyi di ujung kolom ikut terverifikasi. Perbaikan tipe dilakukan lebih dahulu karena langkah pengurutan dan pengelompokan berikutnya bergantung padanya.

Menangani duplikat dan nilai yang hilang#

Duplikat dicari dengan duplicated, ditampilkan terlebih dahulu untuk diperiksa, lalu dibuang dengan drop_duplicates. Baris yang tampil adalah catatan 2026-09-23 yang tercatat dua kali secara persis, dan bentuk data menyusut dari 14 menjadi 13 baris. Pemeriksaan sebelum pembuangan penting karena kemiripan yang tampak kadang justru dua kejadian yang sah, misalnya peminjaman ulang pada tanggal yang berbeda.

python Memeriksa dan membuang baris duplikat
import pandas as pd

pinjam = pd.read_csv("peminjaman-berantakan.csv")

print("bentuk sebelum:", pinjam.shape)
print(pinjam[pinjam.duplicated()])
pinjam = pinjam.drop_duplicates()
print("bentuk sesudah:", pinjam.shape)
text Keluaran
bentuk sebelum: (14, 5)
  tanggal_pinjam  nama kategori                       judul  lama_hari
6     2026-09-23  Dewi    Fiksi  Kumpulan Dongeng Nusantara       12.0
bentuk sesudah: (13, 5)

Nilai yang hilang pada kolom lama_hari diisi median dari nilai yang terisi, karena nilainya berkisar sempit, yaitu 5 sampai 12 hari, dan kolom ini hanya berperan sebagai konteks. Median dipilih sebagai nilai isian karena tahan terhadap nilai ekstrem, dan jumlahnya hanya satu sel sehingga pengaruhnya kecil. Setelah pengisian, kolom dikembalikan menjadi bilangan bulat dengan astype agar tabel bersihnya rapi.

python Mengisi lama_hari yang hilang dengan median
import pandas as pd

pinjam = pd.read_csv("peminjaman-berantakan.csv").drop_duplicates()

median_lama = pinjam["lama_hari"].median()
print("median lama_hari:", median_lama)
pinjam["lama_hari"] = pinjam["lama_hari"].fillna(median_lama).astype("int64")
print()
print(pinjam[pinjam["nama"].str.lower() == "citra"])
text Keluaran
median lama_hari: 8.0

   tanggal_pinjam   nama kategori                        judul  lama_hari
3      2026-09-02  CITRA    Sains         Eksperimen Sederhana          8
7      2026-10-01  Citra    Fiksi  Petualangan di Pulau Tengah         10
10     2026-11-12  CITRA    Sains         Eksperimen Sederhana          5

Keluarannya menunjukkan median 8.0 dan baris Citra tanggal 2026-09-02 yang kosong kini terisi 8. Pencarian barisnya tetap menggunakan str.lower(), karena pada blok ini kapitalisasi nama belum dirapikan, sehingga baris CITRA dan Citra sama-sama ditemukan. Nilai isian median berbeda dari data asli, dan perbedaan itu dicatat sebagai bagian dari keputusan pembersihan.

Validasi dan pipeline lengkap#

Langkah terakhir sebelum menyimpan adalah validasi, yaitu serangkaian pemeriksaan yang menyatakan lolos atau tidak. Validasi berikut memeriksa jumlah baris, duplikat tersisa, sel kosong tersisa, rentang tanggal, dan daftar kategori. Semua langkah sebelumnya diulang dalam blok ini agar pemeriksaannya berdiri sendiri dari berkas mentah.

python Memvalidasi hasil pembersihan
import pandas as pd

pinjam = pd.read_csv("peminjaman-berantakan.csv")
pinjam["tanggal_pinjam"] = pd.to_datetime(
    pinjam["tanggal_pinjam"], format="mixed", dayfirst=True
)
pinjam["nama"] = pinjam["nama"].str.strip().str.title()
pinjam["judul"] = pinjam["judul"].str.strip()
pinjam = pinjam.drop_duplicates()
pinjam["lama_hari"] = pinjam["lama_hari"].fillna(pinjam["lama_hari"].median()).astype("int64")

print("jumlah baris:", len(pinjam))
print("duplikat tersisa:", pinjam.duplicated().sum())
print("sel kosong tersisa:", pinjam.isna().sum().sum())
print("rentang tanggal:", pinjam["tanggal_pinjam"].min().date(), "sampai", pinjam["tanggal_pinjam"].max().date())
print("kategori:", sorted(pinjam["kategori"].unique()))
text Keluaran
jumlah baris: 13
duplikat tersisa: 0
sel kosong tersisa: 0
rentang tanggal: 2026-08-04 sampai 2026-12-02
kategori: ['Fiksi', 'Sains', 'Sejarah']

Semua pemeriksaan menghasilkan nilai yang diharapkan, sehingga data layak disimpan. Karena setiap langkah sudah teruji, keseluruhan prosesnya kini dirangkai menjadi satu skrip utuh bernama pembersihan.py yang dapat dijalankan ulang kapan pun berkas mentahnya diperbarui. Skrip semacam inilah bentuk akhir sebuah pipeline, yaitu pekerjaan pembersihan yang tidak lagi berupa percobaan, melainkan berkas yang dirawat.

python pembersihan.py
import pandas as pd

# muat data mentah
pinjam = pd.read_csv("peminjaman-berantakan.csv")

# perbaiki tipe tanggal dan rapikan teks
pinjam["tanggal_pinjam"] = pd.to_datetime(
    pinjam["tanggal_pinjam"], format="mixed", dayfirst=True
)
pinjam["nama"] = pinjam["nama"].str.strip().str.title()
pinjam["judul"] = pinjam["judul"].str.strip()

# buang baris duplikat
pinjam = pinjam.drop_duplicates()

# isi lama_hari yang hilang dengan median
pinjam["lama_hari"] = pinjam["lama_hari"].fillna(pinjam["lama_hari"].median()).astype("int64")

# urutkan berdasarkan tanggal, lalu simpan hasil bersih
pinjam = pinjam.sort_values("tanggal_pinjam").reset_index(drop=True)
pinjam.to_csv("peminjaman-bersih.csv", index=False)
print("peminjaman-bersih.csv tersimpan,", len(pinjam), "baris")
text Keluaran
peminjaman-bersih.csv tersimpan, 13 baris

Memeriksa hasil bersih#

Berkas bersih dimuat kembali sebagai pemeriksaan penutup, sekaligus memastikan tanggalnya terbaca langsung sebagai tipe tanggal. Blok berikut memuat peminjaman-bersih.csv yang baru saja dibuat oleh skrip pembersihan.

python Memuat kembali hasil bersih
import pandas as pd

bersih = pd.read_csv("peminjaman-bersih.csv")
bersih["tanggal_pinjam"] = pd.to_datetime(bersih["tanggal_pinjam"])
print(bersih)
print()
print(bersih.dtypes)
text Keluaran
   tanggal_pinjam   nama kategori                        judul  lama_hari
0      2026-08-04    Ali    Sains           Ensiklopedia Sains          6
1      2026-08-04   Budi    Sains          Atlas Tubuh Manusia          7
2      2026-08-19   Budi  Sejarah   Sejarah Kerajaan Nusantara          9
3      2026-09-02  Citra    Sains         Eksperimen Sederhana          8
4      2026-09-10   Dewi  Sejarah       Jalur Rempah Nusantara          8
5      2026-09-23   Dewi    Fiksi   Kumpulan Dongeng Nusantara         12
6      2026-10-01  Citra    Fiksi  Petualangan di Pulau Tengah         10
7      2026-10-14   Budi    Fiksi        Cerita Legenda Gunung         11
8      2026-11-03   Dewi    Sains          Atlas Tubuh Manusia          7
9      2026-11-12  Citra    Sains         Eksperimen Sederhana          5
10     2026-11-20    Ali    Sains                Kamus Biologi         10
11     2026-11-28   Dewi  Sejarah   Sejarah Kerajaan Nusantara          8
12     2026-12-02    Ali    Fiksi        Cerita Legenda Gunung          8

tanggal_pinjam    datetime64[ns]
nama                      object
kategori                  object
judul                     object
lama_hari                  int64
dtype: object

Tabel bersih berisi 13 baris yang terurut menurut tanggal, kapitalisasi nama yang seragam, dan kolom lama_hari berupa bilangan bulat. Ringkasan perubahannya sebagai berikut.

AspekSebelumSesudah
jumlah baris1413
baris duplikat10
sel kosong10
tipe tanggalteks campurandatetime64
kapitalisasi namaacakseragam

Berkas peminjaman-bersih.csv tersimpan di folder yang sama dengan berkas mentahnya, dan keduanya dirawat berpasangan. Apabila data mentah bertambah, skrip pembersihan.py dijalankan ulang, dan hasil bersihnya terbentuk kembali dengan langkah yang sama. Data yang berubah tanpa skrip yang menjelaskannya akan kehilangan jejaknya hanya dalam beberapa pekan.

Ringkasan#

  • Inspeksi mendahului perbaikan, yaitu bentuk, tipe, duplikat, dan sel kosong diperiksa sebelum keputusan apa pun diambil.
  • to_datetime dengan format="mixed" dan dayfirst=True mengurai tanggal campuran tanpa salah baca yang diam-diam.
  • Duplikat diperiksa sebelum dibuang, sedangkan sel kosong diisi median bila nilainya berkisar sempit.
  • Pipeline lengkap tersimpan sebagai skrip pembersihan.py yang disertai validasi dan dapat dijalankan ulang.

Referensi#