Setiap pekerja data berjumpa dengan pesan error setiap hari, dan pandas termasuk pustaka yang sering memunculkannya. Kabar baiknya, mayoritas error pandas dirancang informatif: jenis errornya disebut sebagai nama kelas, dan pesannya sering sudah memuat petunjuk perbaikan. Pada chapter ini kita berlatih membaca error pandas dengan tenang — mengenali kelas error yang paling sering muncul, mengekstrak baris pesan yang paling relevan, dan menangkap error secara terprogram dengan try/except agar alur program tetap bisa dilanjutkan.

Kelas Error yang Paling Sering Muncul #

pandas menggunakan sebagian kelas error bawaan Python (KeyError, IndexError, ValueError) dan juga menyediakan kelas khusus di modul pd.errors. Tabel berikut memetakan kelas yang paling sering kita temui saat mengolah data transaksi toko.

Kelas errorKapan munculBentuk pesan pertama
KeyErrorNama kolom atau label index tidak ada'total_omzet' — nama yang dicari
IndexErrorPosisi .iloc berada di luar batassingle positional indexer is out-of-bounds
ValueErrorNilai tidak dapat dikonversi atau diprosesUnable to parse string "2x" at position 1
pd.errors.UndefinedVariableErrorVariabel tidak dikenal di query()name 'omzet' is not defined
pd.errors.OutOfBoundsDatetimeTanggal di luar rentang resolusi dtypeOut of bounds nanosecond timestamp: ...
pd.errors.MergeErrorKondisi merge tidak sesuai validate=dibahas pada chapter Debugging Merge

Tiga kelas terakhir penting diketahui silsilahnya: MergeError dan OutOfBoundsDatetime adalah subclass ValueError, sedangkan UndefinedVariableError adalah subclass NameError. Ketika kita menulis except ValueError, dua kelas pandas tersebut ikut tertangkap oleh penangan yang sama.

Membaca Pesan dari Bawah ke Atas #

Saat kode bermasalah, Python mencetak traceback: daftar baris kode yang sedang dieksekusi, dari lapisan paling luar sampai titik kejadian. Kebiasaan yang efektif adalah membaca traceback dari baris paling bawah karena di sanalah informasi paling penting berada — nama kelas error dan pesannya. Untuk error pandas, pesan biasanya menyebut objek yang bermasalah secara eksplisit: KeyError menuliskan nama kolom atau label yang tidak ditemukan di dalam tanda kutip, dan IndexError menuliskan posisi yang berada di luar batas. Jika nama kolom pada pesan tidak persis sama dengan nama yang kita maksud (misalnya beda spasi atau kapital), penyebabnya langsung terlihat.

Menjalankan Skenario Error Satu per Satu #

Script berikut memicu enam error yang umum terjadi pada data transaksi, lalu menangkapnya satu per satu sehingga program tidak berhenti. Simpan dan jalankan sebagai file, atau unduh langsung dari blok kode di bawah.

python
import pandas as pd

transaksi = pd.DataFrame(
    {
        "kode_transaksi": ["TRX-001", "TRX-002", "TRX-003"],
        "cabang": ["Jakarta", "Bandung", "Surabaya"],
        "jumlah": [2, 5, 1],
    }
)


def uji_error(nama: str, tipe: type, aksi) -> None:
    """Jalankan aksi, tangkap error yang diharapkan, tampilkan pesan pertamanya."""
    try:
        aksi()
    except tipe as exc:
        print(f"[{nama}] {type(exc).__name__}")
        print(f"  pesan : {str(exc).splitlines()[0]}")


# 1. KeyError: nama kolom tidak ada di DataFrame
uji_error("akses kolom", KeyError, lambda: transaksi["total_omzet"])

# 2. KeyError: pasangan baris-kolom pada .loc
uji_error("loc sel", KeyError, lambda: transaksi.loc[0, "total_omzet"])

# 3. IndexError: posisi baris di luar batas
uji_error("iloc", IndexError, lambda: transaksi.iloc[99])

# 4. UndefinedVariableError: variabel tidak dikenal di query
uji_error("query", pd.errors.UndefinedVariableError,
          lambda: transaksi.query("jumlah > omzet"))

# 5. OutOfBoundsDatetime: datetime64[us] dikonversi ke [ns] yang lebih sempit
tanggal = pd.Series(pd.to_datetime(["9999-01-01"]))
uji_error("dtype ns", pd.errors.OutOfBoundsDatetime,
          lambda: tanggal.astype("datetime64[ns]"))

# 6. ValueError: teks tidak dapat dibaca sebagai angka
uji_error("to_numeric", ValueError,
          lambda: pd.to_numeric(pd.Series(["10", "2x"])))

print()
# 7. Pesan multi-baris: ambil baris pertamanya saja
try:
    pd.to_datetime(pd.Series(["2024-01-01", "01/02/2024"]))
except ValueError as exc:
    baris = str(exc).splitlines()
    print(f"Pesan error ini {len(baris)} baris; baris pertamanya:")
    print(f"  {baris[0]}")

Output yang Dihasilkan:

text
[akses kolom] KeyError
  pesan : 'total_omzet'
[loc sel] KeyError
  pesan : 'total_omzet'
[iloc] IndexError
  pesan : single positional indexer is out-of-bounds
[query] UndefinedVariableError
  pesan : name 'omzet' is not defined
[dtype ns] OutOfBoundsDatetime
  pesan : Out of bounds nanosecond timestamp: 9999-01-01 00:00:00
[to_numeric] ValueError
  pesan : Unable to parse string "2x" at position 1

Pesan error ini 4 baris; baris pertamanya:
  time data "01/02/2024" doesn't match format "%Y-%m-%d". You might want to try:

Mari kita bedah bagian pentingnya:

  1. Fungsi uji_error(nama, tipe, aksi): helper kecil yang menjalankan aksi() di dalam blok try, menangkap error bertipe tipe, lalu mencetak nama kelas error dan baris pertama pesannya. Dengan helper ini, satu script bisa mendemokan banyak error tanpa berhenti di error pertama.
  2. transaksi["total_omzet"] dan transaksi.loc[0, "total_omzet"]: keduanya melempar KeyError dengan pesan yang sama, yaitu 'total_omzet'. Pesan sependek ini cukup untuk menemukan akar masalah: nama kolom yang kita maksud tidak ada, mungkin karena salah eja atau kolom baru dibuat di tahap lain.
  3. transaksi.iloc[99]: melempar IndexError dengan pesan single positional indexer is out-of-bounds. DataFrame hanya punya 3 baris, sedangkan posisi 99 tidak ada.
  4. transaksi.query("jumlah > omzet"): melempar pd.errors.UndefinedVariableError. Kolom omzet tidak ada, sehingga parser query() menolak ekspresi tersebut dengan pesan name 'omzet' is not defined.
  5. tanggal.astype("datetime64[ns]"): series tanggal tahun 9999 bawaan datetime64[us] dikonversi ke resolusi ns yang lebih sempit, sehingga muncul pd.errors.OutOfBoundsDatetime.
  6. pd.to_numeric(pd.Series(["10", "2x"])): melempar ValueError, dan pesannya menunjuk posisi data yang bermasalah: Unable to parse string "2x" at position 1. Pesan semacam ini sekaligus menjadi peta lokasi data yang perlu diperiksa.

Menangkap Baris Pesan Pertama #

Pesan error pandas kadang terdiri atas beberapa baris, seperti contoh pd.to_datetime pada output di atas yang memberi tiga saran format sekaligus. Untuk logging atau pemeriksaan otomatis, baris pertama biasanya sudah cukup: kalimat inti penyebab error hampir selalu ditulis lebih dulu. Pola str(exc).splitlines()[0] pada script mengambil baris tersebut secara deterministik, sehingga output program tetap rapi dan mudah dibandingkan antar eksekusi.

Membaca error adalah separuh dari pekerjaan debugging; separuh lainnya adalah menelusuri kenapa hasil operasi berbeda dari ekspektasi meski tidak ada error. Penyebab paling sering pada pandas adalah perbedaan index dan aturan alignment, dan itulah materi chapter berikutnya, Debugging Index dan Alignment.

Referensi resmi untuk chapter ini: pandas.errors.UndefinedVariableError , pandas.errors.OutOfBoundsDatetime , dan Gotchas pandas .