Sebelum satu nilaipun diubah, seorang pembersih data yang baik selalu memeriksa lebih dulu. Data hasil ekspor dari aplikasi kasir, formulir, atau penggabungan beberapa sistem hampir selalu membawa masalah tersembunyi: nilai hilang, baris terekam dua kali, kolom angka yang ternyata teks, hingga harga yang salah ketik. Pada chapter ini kita membangun kebiasaan pemeriksaan awal yang sistematis memakai pandas — dari head(), shape, dtypes, info(), describe(), sampai isna() dan duplicated() — sehingga setiap masalah ketahuan sebelum kita memutuskan cara membersihkannya pada chapter-chapter berikutnya.
Berkas Latihan dari Aplikasi Kasir #
Berkas latihan kita adalah penjualan_kotor.csv — ekspor penjualan Toko Kopi Kita selama enam hari pada Januari 2026. Dua belas baris itu terlihat wajar di sekilas, tetapi sesungguhnya menyimpan enam jenis masalah berbeda yang akan kita temukan satu per satu. Aplikasi kasir menandai sel kosong dengan tanda -, sehingga kita mendaftarkan penanda itu lewat na_values sejak pembacaan — persis seperti yang kita pelajari pada chapter Membaca File CSV
.
tanggal,produk,jumlah,harga,pelanggan
2026-01-15,kopi susu,3,24000,Budi
2026-01-15,teh tawar,2,20000,Siti
2026-01-16,kopi susu,1,24000,Dewi
2026-01-16,matcha latte,4,28000,Rani
2026-01-17,americano,2,22000,Budi
2026-01-17,teh tawar,-,20000,Agus
2026-01-18,kopi susu ,5,24000,Siti
2026-01-18,americano,1,22000,-
2026-01-19,Americano,2,22000,Rani
2026-01-19,kopi susu,2,240000,Dewi
2026-01-20,matcha latte,2,28000,Agus
2026-01-20,matcha latte,2,28000,AgusMelihat Cuplikan Data dengan head dan tail #
Langkah pertama adalah melihat wujud data secara langsung. head(7) menampilkan tujuh baris pertama; tail(3) menampilkan tiga baris terakhir. Dua cuplikan pendek ini biasanya cukup untuk mengenali bentuk kolom, gaya penulisan, dan beberapa gejala yang mencurigakan — misalnya nilai NaN atau angka yang tidak wajar.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
print(df.head(7))
print()
print(df.tail(3))Output yang Dihasilkan:
tanggal produk jumlah harga pelanggan
0 2026-01-15 kopi susu 3.0 24000 Budi
1 2026-01-15 teh tawar 2.0 20000 Siti
2 2026-01-16 kopi susu 1.0 24000 Dewi
3 2026-01-16 matcha latte 4.0 28000 Rani
4 2026-01-17 americano 2.0 22000 Budi
5 2026-01-17 teh tawar NaN 20000 Agus
6 2026-01-18 kopi susu 5.0 24000 Siti
tanggal produk jumlah harga pelanggan
9 2026-01-19 kopi susu 2.0 240000 Dewi
10 2026-01-20 matcha latte 2.0 28000 Agus
11 2026-01-20 matcha latte 2.0 28000 AgusMari kita telaah baris-barisnya:
- Baris 3 (
pd.read_csv(...)): berkas dibaca menjadi DataFrame; setiap-diubah menjadiNaN, penanda nilai hilang milik pandas. - Baris 4 (
df.head(7)): tujuh baris pertama tampil dengan rapi. Perhatikan baris berindeks 5: kolomjumlahberisiNaN— di berkas aslinya tertulis-. - Baris 6 (
df.tail(3)): tiga baris terakhir menyimpan dua gejala sekaligus: harga240000yang jauh di atas harga kopi susu biasanya (24000), dan dua baris berindeks 10-11 yang tampak identik.
Pada tahap ini kita belum menyimpulkan apa pun — kita hanya mencatat dugaan. Pemeriksaan berikutnya bertugas membuktikan apakah dugaan itu benar.
Mengukur Ukuran dan Tipe dengan shape dan dtypes #
Pertanyaan paling dasar tentang sebuah dataset: berapa baris dan kolomnya, serta tipe apa yang tersimpan di tiap kolom. Dua hal itu dijawab oleh atribut shape dan dtypes. Tipe kolom menentukan operasi apa yang sah: kolom object (teks) tidak bisa dihitung rata-ratanya, sedangkan kolom datetime64 bisa diurutkan kronologis. Rujukan tata cara pembacaan berkas dan penentu tipe tersedia di dokumentasi pandas.read_csv
.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
print("Ukuran data (baris, kolom):", df.shape)
print()
print(df.dtypes)Output yang Dihasilkan:
Ukuran data (baris, kolom): (12, 5)
tanggal object
produk object
jumlah float64
harga int64
pelanggan object
dtype: objectMari kita telaah hasilnya:
df.shape: data memuat 12 baris dan 5 kolom — angka yang perlu kita ingat sebagai patokan sebelum dan sesudah pembersihan.df.dtypes: kolomtanggalbertipeobject, padahal isinya tanggal — pandas tidak menebak tanggal secara otomatis, sehingga kolom ini belum bisa diurutkan secara kronologis.- Kolom
jumlahbertipefloat64: satu nilaiNaNmemaksa seluruh kolom naik ke tipe desimal, karena tipe bilangan bulat tidak sanggup menyimpanNaN. Kolomhargatetapint64karena isinya lengkap.
Melihat Kelengkapan Baris dengan info #
info() merangkum tiga pemeriksaan sebelumnya dalam satu cetakan: jumlah baris, nama kolom beserta tipe, dan yang paling berharga — Non-Null Count, yaitu banyaknya baris yang benar-benar berisi nilai pada tiap kolom. Selisih antara jumlah baris dan non-null count adalah jumlah nilai hilang.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
df.info()Output yang Dihasilkan:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 12 entries, 0 to 11
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 tanggal 12 non-null object
1 produk 12 non-null object
2 jumlah 11 non-null float64
3 harga 12 non-null int64
4 pelanggan 11 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 612.0+ bytesCetakan tersebut memberi tiga temuan. Pertama, RangeIndex: 12 entries mengonfirmasi 12 baris. Kedua, kolom jumlah hanya memiliki 11 nilai non-null — ada satu nilai hilang. Ketiga, kolom pelanggan juga hanya 11 non-null. Bandingkan dengan df.isna() yang akan kita jalankan sebentar lagi: info() memperlihatkan gambaran umum, sedangkan penghitungan eksplisit memudahkan pencatatan.
Ringkasan Statistik dengan describe #
describe() menghitung statistik ringkas untuk semua kolom numerik sekaligus: jumlah nilai (count), rata-rata (mean), simpangan baku (std), nilai terkecil-terbesar, serta kuartil (25%, 50%, 75%). Kuartil adalah nilai batas ketika data diurutkan lalu dibagi empat bagian sama banyak. Panduan penggunaan fungsi agregasi semacam ini tersedia pada pandas user guide
.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
print(df.describe())Output yang Dihasilkan:
jumlah harga
count 11.000000 12.000000
mean 2.363636 41833.333333
std 1.206045 62473.024482
min 1.000000 20000.000000
25% 2.000000 22000.000000
50% 2.000000 24000.000000
75% 2.500000 28000.000000
max 5.000000 240000.000000Mari kita baca angka-angkanya dengan teliti:
- Kolom
jumlah:counthanya 11 dari 12 baris — bukti lain satu nilai hilang. Rata-rata 2,36 cangkir per transaksi terasa wajar untuk sebuah kafe. - Kolom
harga:meansekitar 41.833, padahal separuh transaksi berada di harga 24.000 ke bawah dan kuartil ketiganya 28.000. Nilaimax240.000 — hampir sembilan kali menu termahal — hampir pasti salah ketik, bukan menu premium. - Pola umumnya: ketika
maxmenjulang jauh di atas kuartil ketiga, curigai pencilan (outlier) atau salah ketik. Kita akan menanganinya khusus pada chapter Menangani Outlier .
Menghitung Nilai Hilang dan Baris Duplikat #
Dugaan dari info() dan describe() perlu angka pasti. Dua perintah berikut menghitungnya: isna().sum() menjumlahkan nilai hilang per kolom, sedangkan duplicated().sum() menghitung baris yang sama persis dengan baris sebelumnya.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
print("Nilai hilang per kolom:")
print(df.isna().sum())
print()
print("Baris duplikat penuh:", df.duplicated().sum())Output yang Dihasilkan:
Nilai hilang per kolom:
tanggal 0
produk 0
jumlah 1
harga 0
pelanggan 1
dtype: int64
Baris duplikat penuh: 1Hasilnya lugas: satu nilai hilang di jumlah, satu di pelanggan, dan satu baris tercatat dua kali secara penuh — baris terakhir 2026-01-20 yang tampil kembar pada tail(3) di awal chapter. Tiga temuan ini menjadi pekerjaan utama dua chapter berikutnya.
Memeriksa Nilai Unik Kolom Teks #
Kolom teks menyimpan masalah yang tidak terlihat di describe(): nilai yang tertulis mirip tetapi dianggap berbeda oleh komputer. value_counts() menghitung frekuensi tiap nilai, dan daftar nilai unik hasil sorted(...) memperlihatkan setiap perbedaan sekecil apa pun — termasuk spasi tersembunyi.
import pandas as pd
df = pd.read_csv("penjualan_kotor.csv", na_values=["-"])
print(df["produk"].value_counts())
print()
print("Daftar nilai unik (urut abjad):")
print(sorted(df["produk"].unique()))Output yang Dihasilkan:
produk
kopi susu 3
matcha latte 3
teh tawar 2
americano 2
kopi susu 1
Americano 1
Name: count, dtype: int64
Daftar nilai unik (urut abjad):
['Americano', 'americano', 'kopi susu', 'kopi susu ', 'matcha latte', 'teh tawar']Tabel frekuensi tersebut membuka masalah yang tersembunyi rapi:
'kopi susu 'dengan spasi di ujung hadir sebagai nilai tersendiri: pada tabel frekuensi,kopi susutampil dua kali dengan jumlah berbeda (3 dan 1) padahal barisnya tampak sama. Satu transaksi terpisah dari tiga transaksi kopi susu lainnya hanya karena spasi tersembunyi.'Americano'berhuruf besar juga dihitung terpisah dari'americano'.- Akibatnya: penjualan per produk akan melaporkan enam produk padahal sebenarnya hanya ada empat. Perbaikannya menjadi pokok chapter Membersihkan Teks dan Menangani Data Tidak Konsisten .
Daftar Periksa Pemeriksaan Awal #
Pemeriksaan awal yang kita lakukan di atas dapat dirangkum menjadi daftar periksa ringkas. Kolom temuan memuat apa yang sebenarnya kita temukan pada penjualan_kotor.csv — bukti bahwa daftar periksa ini bekerja pada data nyata, bukan sekadar teori.
| Pertanyaan | Perintah | Temuan pada berkas latihan |
|---|---|---|
| Bagaimana wujud datanya? | df.head(), df.tail() | Ada NaN; dua baris akhir tampak kembar |
| Berapa baris dan kolomnya? | df.shape | 12 baris, 5 kolom |
| Tipe apa di tiap kolom? | df.dtypes, df.info() | tanggal masih object; jumlah naik ke float64 |
| Berapa nilai yang hilang? | df.isna().sum() | 1 di jumlah, 1 di pelanggan |
| Ada baris terekam dua kali? | df.duplicated().sum() | 1 baris duplikat penuh |
| Adakah angka tidak wajar? | df.describe() | max harga 240.000 jauh di atas kuartil ketiga |
| Adakah teks bervarian? | value_counts(), unique() | Spasi di ujung 'kopi susu '; kapital 'Americano' |
Rangkuman #
- Pemeriksaan awal selalu mendahului pembersihan: kita mencatat masalah lebih dulu, baru memutuskan perbaikannya pada chapter yang sesuai.
shapedandtypesmenjawab ukuran serta tipe;info()menambahkan non-null count yang mengungkap kolom tidak lengkap.describe()merangkum statistik numerik; jarak besar antara kuartil ketiga danmaxadalah penanda pencilan atau salah ketik.isna().sum()danduplicated().sum()mengubah dugaan menjadi hitungan pasti;value_counts()membongkar variasi teks tersembunyi.- Berkas latihan kita terbukti memuat enam masalah: nilai hilang, duplikat, tipe kolom salah, teks bervarian, dan harga salah ketik.
Koleksi masalah telah lengkap, dan urutan pengerjaannya mengikuti urutan daftar periksa di atas. Masalah pertama yang paling sering dijumpai di data nyata adalah nilai hilang — kapan baris boleh dibuang, kapan harus diisi, dan diisi dengan apa. Kita bedah strateginya pada chapter berikutnya, Menangani Missing Values .