Tipe data yang salah adalah masalah yang paling sering lolos dari pemeriksaan sepintas. Kolom terlihat terisi rapi, tetapi isinya adalah teks seperti "250,000", sehingga penjumlahan berhenti dengan error dan pengurutan menyusun "1000" sebelum "250". Chapter ini menutup rangkaian pembersihan dasar: kita melihat bagaimana tipe yang salah muncul saat data dibaca, lalu memperbaikinya dengan astype() dan pd.to_numeric(). Agar tetap runnable offline, contoh membangun CSV di memori dengan StringIO, meniru hasil ekspor yang kotor.

Gejala Kolom dengan Tipe yang Salah #

Tanda paling umum ada tiga. Pertama, operasi aritmetika gagal: menjumlahkan kolom teks memunculkan TypeError. Kedua, urutan menyimpang: teks diurutkan karakter demi karakter sehingga "1000" tampil sebelum "250". Ketiga, df.dtypes menampilkan str untuk kolom yang seharusnya angka, atau float64 untuk kolom bilangan bulat yang kehilangan satu sel. Ketiganya bisa dideteksi sebelum operasi apa pun dijalankan, cukup dengan melihat df.dtypes atau pandas.DataFrame.info .

Membaca CSV yang Terbaca Salah #

Skrip berikut menyusun CSV di memori dengan dua penyakit: nilai total_belanja ditulis bergaya ribuan "250,000" sehingga terbaca sebagai teks, dan satu sel umur kosong sehingga kolom bilangan bulat jatuh ke float64. Method read_csv() kita arahkan ke StringIO(csv_kotor) agar tidak butuh file di disk:

python
import pandas as pd
from io import StringIO

csv_kotor = """id_pesanan,nama_pelanggan,kota,umur,total_belanja
PSC-101,Budi,Jakarta,29,"250,000"
PSC-102,Siti,Bandung,34,"480,000"
PSC-103,Dewi,Surabaya,,"150,000"
PSC-104,Andi,Jakarta,41,"320,000"
PSC-105,Rina,Bandung,27,"275,000"
"""

pesanan = pd.read_csv(StringIO(csv_kotor))
print(pesanan.dtypes)
print()

pesanan["total_belanja"] = pesanan["total_belanja"].str.replace(",", "").astype("int64")
pesanan["umur"] = pesanan["umur"].astype("Int64")
print(pesanan.dtypes)
print()
print(pesanan)
print()
print("Total seluruh pesanan:", pesanan["total_belanja"].sum())

Output yang Dihasilkan:

text
id_pesanan            str
nama_pelanggan        str
kota                  str
umur              float64
total_belanja         str
dtype: object

id_pesanan          str
nama_pelanggan      str
kota                str
umur              Int64
total_belanja     int64
dtype: object

  id_pesanan nama_pelanggan      kota  umur  total_belanja
0    PSC-101           Budi   Jakarta    29         250000
1    PSC-102           Siti   Bandung    34         480000
2    PSC-103           Dewi  Surabaya  <NA>         150000
3    PSC-104           Andi   Jakarta    41         320000
4    PSC-105           Rina   Bandung    27         275000

Total seluruh pesanan: 1475000

Mari kita telaah peran setiap bagian skrip di atas:

  1. Baris 4-10 (csv_kotor = """..."""): string CSV sumber; nilai ribuan dibungkus tanda kutip agar komanya tidak dianggap pemisah kolom.
  2. Baris 12 (pesanan = pd.read_csv(StringIO(csv_kotor))): hasil pembacaan memperlihatkan total_belanja ber-dtype str dan umur ber-dtype float64, dua gejala yang sedang kita cari.
  3. Baris 16: rantai dua operasi pada kolom total_belanja: .str.replace(",", "") menghapus koma ribuan, lalu .astype("int64") mengubah teks bersih menjadi bilangan bulat.
  4. Baris 17 (pesanan["umur"] = pesanan["umur"].astype("Int64")): Int64 dengan huruf besar I adalah tipe nullable; int64 biasa tidak mampu menampung NaN sehingga konversi langsung akan error.
  5. Baris 22: setelah tipe benar, sum() menghasilkan 1.475.000, perhitungan yang mustahil dilakukan saat kolom masih teks.

Peta Alat Perbaikan Tipe #

AlatKapan dipakai
astype("int64")Kolom bersih tanpa sel kosong
astype("Int64")Bilangan bulat dengan sel kosong (nullable)
astype("float64")Angka desimal, termasuk yang mengandung NaN
pd.to_numeric(errors="coerce")Kolom berisi nilai tak sah; nilai yang gagal diparse menjadi NaN untuk dibersihkan kemudian

pd.to_numeric dari halaman pandas.to_numeric layak dibedah lebih jauh karena lebih sabar daripada astype(). Dengan parameter bawaan, nilai yang tidak bisa diparse memicu ValueError; dengan errors="coerce", nilai tersebut berubah menjadi NaN sehingga sel lain tetap terselamatkan. Bila satu kolom angka mengandung teks asing seperti "bukan angka", pola pd.to_numeric(ser, errors="coerce") mengubahnya menjadi kekosongan yang siap ditangani dengan dropna() atau fillna() dari Chapter-Chapter sebelumnya. Untuk konversi massal seluruh kolom ke tipe terbaiknya, method df.convert_dtypes() menebak tipe nullable yang paling sesuai.

Dengan tipe yang benar, dataset pesanan akhirnya layak dihitung, diurutkan, dan digabungkan; perilaku kekosongan pada tiap tipe tetap bisa dirujuk ke panduan Working with missing data . Section Data Cleaning belum berhenti di sini: dua masalah sering tersisa justru di dalam teks, seperti spasi berlebih dan kapitalisasi yang tidak seragam. Chapter Membersihkan Teks melanjutkan pekerjaan kita ke ranah tersebut dengan method .str milik pandas.