Chapter sebelumnya membuat MultiIndex dan melakukan akses dari level terluar ke dalam. Kebutuhan analisis sering berbalik arah: kita ingin melompat ke level mana pun, misalnya “tampilkan semua cabang pada bulan 1 saja” atau “tukar urutan level agar laporan terbaca per kategori”. Chapter ini membahas alat navigasi level: xs() untuk mengambil cross-section satu level, swaplevel() dan reorder_levels() untuk menyusun ulang posisi level, droplevel() untuk membuang level, serta pemeriksaan isi level lewat get_level_values(). Dataset penjualan 27 baris dari chapter sebelumnya tetap kita pakai.

xs(): Cross-Section pada Level Mana Pun #

Method xs() mengambil potongan data pada satu level tanpa menyentuh level lain, seperti pemotongan lintas pada kue berlapis — sisi yang dipotong hilang dari hasil. Script berikut memakai dataset yang sama dan menunjukkan varian pemanggilannya.

python
import pandas as pd

kota_list = ["Jakarta", "Bandung", "Surabaya"]
bulan_list = [1, 2, 3]
kategori_list = ["Elektronik", "Pakaian", "Makanan"]
dasar = {"Elektronik": 420, "Pakaian": 260, "Makanan": 150}

baris = []
for kota in kota_list:
    for bulan in bulan_list:
        for kategori in kategori_list:
            omzet = dasar[kategori] + 30 * kota_list.index(kota) + 12 * (bulan - 1)
            baris.append((kota, bulan, kategori, omzet))

penjualan = pd.DataFrame(baris, columns=["kota", "bulan", "kategori", "omzet"])
multi = penjualan.set_index(["kota", "bulan", "kategori"]).sort_index()

# xs() tanpa level eksplisit: seleksi pada level terluar
print(multi.xs("Bandung"))
print()

# xs() dengan level nama: seleksi di level mana pun
print(multi.xs(1, level="bulan").head(5))
print()

# drop_level=False: level yang diseleksi tetap ada di hasil
print(multi.xs("Bandung", drop_level=False).head(3))
print()

# xs() dengan tuple pada beberapa level sekaligus
print(multi.xs(("Jakarta", 2), level=["kota", "bulan"]))
print()

# swaplevel: tukar posisi dua level, lalu sort_index merapikan
print(multi.swaplevel().sort_index().head(4))
print()

# reorder_levels: susun ulang urutan semua level
print(multi.reorder_levels(["bulan", "kategori", "kota"]).sort_index().head(4))
print()

# droplevel: buang satu level dari index
print(multi.droplevel("kategori").head(4))
print()

# memeriksa isi level
print("label unik kategori  :", multi.index.get_level_values("kategori").unique().tolist())
print("isi levels[0] (kota) :", multi.index.levels[0].tolist())

Output yang Dihasilkan:

text
                  omzet
bulan kategori         
1     Elektronik    450
      Makanan       180
      Pakaian       290
2     Elektronik    462
      Makanan       192
      Pakaian       302
3     Elektronik    474
      Makanan       204
      Pakaian       314

                    omzet
kota    kategori         
Bandung Elektronik    450
        Makanan       180
        Pakaian       290
Jakarta Elektronik    420
        Makanan       150

                          omzet
kota    bulan kategori         
Bandung 1     Elektronik    450
              Makanan       180
              Pakaian       290

            omzet
kategori         
Elektronik    432
Makanan       162
Pakaian       272

                          omzet
kota    kategori   bulan       
Bandung Elektronik 1        450
                   2        462
                   3        474
        Makanan    1        180

                           omzet
bulan kategori   kota           
1     Elektronik Bandung     450
                 Jakarta     420
                 Surabaya    480
      Makanan    Bandung     180

               omzet
kota    bulan       
Bandung 1        450
        1        180
        1        290
        2        462

label unik kategori  : ['Elektronik', 'Makanan', 'Pakaian']
isi levels[0] (kota) : ['Bandung', 'Jakarta', 'Surabaya']

Mari kita bedah bagian pentingnya:

  1. Baris 19 (xs("Bandung")): tanpa argumen level, xs() menyeleksi level terluar; hasilnya sembilan baris Bandung dengan level kota sudah tidak ada di index, tersisa bulan dan kategori.
  2. Baris 23 (level="bulan"): argumen level menerima nama maupun posisi angka, sehingga seleksi bisa dilakukan di level mana pun; kelima baris pertama menunjukkan kota Bandung dan Jakarta untuk bulan 1.
  3. Baris 27 (drop_level=False): level yang diseleksi dipertahankan di hasil, berguna ketika hasil akan digabung kembali dengan data lain yang masih membawa label tersebut.
  4. Baris 31 (tuple dua level): level juga menerima list, sehingga xs(("Jakarta", 2), level=["kota", "bulan"]) mengambil tiga baris kategori untuk kombinasi Jakarta–bulan 2 sekaligus.

swaplevel() menukar posisi dua level, secara default level 0 dan level 1; hasilnya terlihat pada tampilan output kelima, tempat bulan kini menjadi level terluar dan kategori berpindah ke tengah. Nilai 450, 462, 474 pada tiga baris pertamanya adalah omzet Elektronik Bandung untuk bulan 1 sampai 3, bukti bahwa data tidak berubah — hanya susunan labelnya. Method reorder_levels() lebih umum: satu list menentukan urutan seluruh level sekaligus, seperti tampilan output keenam yang memajukan bulan ke posisi pertama. Keduanya tidak mengurutkan baris, jadi pemanggilan sort_index() setelahnya adalah pola yang sebaiknya menjadi kebiasaan bila data akan diirisan lagi.

Membuang Level dan Memeriksa Isinya #

droplevel("kategori") menghapus satu level dan menyisakan index dua level; perhatikan pada output bahwa pasangan Bandung, 1 kini muncul tiga kali karena tiga kategori sebelumnya membedakan baris-baris itu. Label duplikat seperti ini sah dalam pandas, tetapi seleksi .loc menjadi mengembalikan beberapa baris sekaligus. Untuk pemeriksaan isi, get_level_values("kategori").unique() mengembalikan label unik sesuai urutan kemunculan di data, sedangkan index.levels[0] selalu menyimpan label level terluar dalam urutan leksikografis.

Dengan navigasi level di tangan, satu-satunya alat seleksi bertingkat yang belum kita kuasai adalah irisan dan kombinasi beberapa level sekaligus pada .loc. Chapter berikutnya menutup celah itu dengan IndexSlice, slicer resmi pandas untuk MultiIndex, beserta aturan urutan index yang menyertainya.

Referensi resmi untuk chapter ini: user guide MultiIndex / Advanced Indexing , pandas.DataFrame.xs , dan pandas.DataFrame.swaplevel .

Index bertingkat membuka satu risiko baru: label yang sama muncul lebih dari satu kali tanpa peringatan apa pun. Chapter berikutnya membahas cara mengenali label duplikat dan melarangnya lewat set_flags(allows_duplicate_labels=False).