hierarchical-indexing membahas index bertingkat, dan chapter ini menyentuh kondisi index yang paling sering menipu: dua baris atau lebih berbagi label yang sama. Label duplikat bukan galat di pandas — index memang boleh ganda — tetapi kondisi itu mengubah makna seleksi secara halus dan menjadi sumber bug klasik saat menggabungkan data. pandas memberi dua lapis pertahanan: deteksi lewat has_duplicates() dan duplicated(), serta larangan menyeluruh lewat set_flags(allows_duplicate_labels=False). Chapter ini membahas perilaku seleksi pada label ganda, kontrak larangan duplikat, dan pembersihannya.

Seleksi pada Label Ganda #

Saat df.loc["Januari"] dijalankan pada index yang berisi dua label Januari, pandas mengembalikan semua baris berlabel itu — hasilnya DataFrame dua baris, bukan Series satu baris. Perilaku ini sah dan berguna, tetapi bermata dua: kode yang dirancang untuk menerima satu baris tiba-tiba menerima dua, dan kesalahan datanya baru terasa jauh di hilir. Pola yang rawan adalah penggabungan; concat dua tabel yang indexnya beririsan secara bawaan menghasilkan index ganda, kebiasaan yang sudah kita kelola dengan ignore_index pada chapter concat. merge() tidak menimbulkan masalah ini karena hasil merge selalu index baru.

python
import pandas as pd

df = pd.DataFrame(
    {"omzet": [450, 380, 210]},
    index=["Januari", "Januari", "Februari"],
)
print("index ganda:", df.index.has_duplicates)

# loc pada label ganda mengembalikan SEMUA baris berlabel itu
print(df.loc["Januari"])

# larangan dinyatakan sejak awal: set_flags menolak index ganda
try:
    df.set_flags(allows_duplicate_labels=False)
except Exception as e:
    print(type(e).__name__, "saat set_flags")

# mendeteksi dan membuang baris index ganda
print("\nduplicated:", df.index.duplicated().tolist())
print(df[~df.index.duplicated()])

Output yang Dihasilkan:

text
index ganda: True
         omzet
Januari    450
Januari    380
DuplicateLabelError saat set_flags

duplicated: [False, True, False]
          omzet
Januari     450
Februari    210

Mari kita telaah baris-baris kuncinya:

  1. Baris 7: df.index.has_duplicates bernilai True — dua baris berbagi label Januari.
  2. Baris 10: df.loc["Januari"] mengembalikan dua baris sekaligus, bukan satu.
  3. Baris 13-16: set_flags(allows_duplicate_labels=False) dipanggil pada data yang indexnya sudah ganda, dan pandas langsung menolak dengan DuplicateLabelError.
  4. Baris 19-20: df.index.duplicated() menandai kemunculan kedua dan seterusnya sebagai True, sehingga negasinya menyaring index menjadi unik.

Kontrak allows_duplicate_labels #

Flag allows_duplicate_labels=False adalah pernyataan niat pada level objek: “objek ini tidak boleh pernah punya label ganda, mulai sekarang”. pandas menegakkan kontrak itu di dua pintu — saat flag dipasang pada data yang sudah ganda, dan saat operasi berikutnya berusaha menciptakan label ganda pada objek terflag, misalnya concat yang membawa label beririsan. Operasi yang melanggar melempar DuplicateLabelError dengan pesan yang menyebut label persis mana yang bermasalah. Karena flag ikut mewarisi ke hasil operasi, kontrak ini cocok dinyatakan di awal pipeline: data masuk diterima hanya bila kuncinya unik, dan setiap tahap berikutnya memeriksa dengan otomatis.

Membersihkan Label Ganda #

Tiga alat membersihkan index ganda: df.index.duplicated() yang menghasilkan mask per baris (kemunculan kedua dan seterusnya bernilai True), df.index.unique() yang mengembalikan label unik, dan df[~df.index.duplicated()] sebagai pola buang-salinan-terakhir. Bila label ganda memang sah — misalnya deret harian dua toko dengan tanggal sebagai index — penyelesaiannya bukan membuang baris melainkan memperluas index menjadi MultiIndex dengan set_index("toko", append=True), keputusan struktural yang membedakan “data salah” dari “grup belum dinyatakan”. Section Pengujian dan Debugging nanti memakai pemeriksaan yang sama sebagai asersi schema.

Dengan ini kotak peralatan index bertingkat tuntas: MultiIndex untuk struktur, advanced-selection untuk navigasi, dan larangan duplikat untuk keamanan. Chapter berikutnya turun ke level seleksi lanjutan: .xs dan teknik menyasar lapisan tertentu dari index bertingkat.

Dokumentasi resmi yang relevan: User Guide: Duplicate Labels sebagai rujukan utama kontrak ini, pandas.DataFrame.set_flags untuk parameter allows_duplicate_labels, dan pandas.Index.duplicated untuk alat deteksinya.