melt() bekerja pada kolom biasa, sedangkan stack() dan unstack() bekerja pada struktur index. stack() menumpuk kolom menjadi level index terdalam sehingga DataFrame lebar berubah menjadi Series panjang ber-MultiIndex; unstack() memindahkan level index menjadi kolom sebaliknya. Keduanya adalah mesin pembentuk ulang di balik pivot() dan melt(), sehingga memahaminya membuat perilaku kedua method itu terasa jelas. Pada Chapter ini kita memutar tabel penjualan dua kota dengan stack dan unstack, memilih level yang dipindahkan, dan mencatat perubahan perilaku penting pada pandas 3.0.
stack(): Kolom Menjadi Level Index Terdalam #
Method stack() tanpa argumen memindahkan seluruh label kolom ke level index baru yang menempel di posisi terdalam. File berikut memakai tabel dengan index bernama bulan dan nama axis kolom kota, lalu memutar-mutarnya bolak-balik.
import pandas as pd
lebar = pd.DataFrame({
"Bandung": [120, 135],
"Jakarta": [200, 180],
}, index=["Jan", "Feb"])
lebar.index.name = "bulan"
lebar.columns.name = "kota"
print(lebar)
print()
# stack: kolom -> level index terdalam
st = lebar.stack()
print(st)
print()
print(st.index.names)
print()
# unstack membalikkan stack
print(st.unstack())
print()
# unstack(level=...) memilih level yang dipindahkan
panjang = pd.DataFrame({
"kota": ["Bandung", "Bandung", "Jakarta"],
"bulan": ["Jan", "Feb", "Jan"],
"omzet": [120, 135, 200],
})
multi = panjang.set_index(["kota", "bulan"])["omzet"]
print(multi.unstack(level="kota"))
print()
# Kombinasi yang tidak ada menjadi NaN, bisa diisi fill_value
print(multi.unstack(fill_value=0))
print()
# stack implementasi baru TIDAK menghapus baris NaN
dengan_nan = pd.DataFrame({
"A": [1.0, 2.0],
"B": [3.0, None],
}, index=["x", "y"])
dengan_nan.index.name = "id"
dengan_nan.columns.name = "grup"
print(dengan_nan.stack())
print()
# Parameter dropna sudah dihapus pada pandas 3.0
try:
dengan_nan.stack(dropna=False)
except ValueError as e:
print("ValueError:", e)Output yang Dihasilkan:
kota Bandung Jakarta
bulan
Jan 120 200
Feb 135 180
bulan kota
Jan Bandung 120
Jakarta 200
Feb Bandung 135
Jakarta 180
dtype: int64
['bulan', 'kota']
kota Bandung Jakarta
bulan
Jan 120 200
Feb 135 180
kota Bandung Jakarta
bulan
Feb 135.0 NaN
Jan 120.0 200.0
bulan Feb Jan
kota
Bandung 135 120
Jakarta 0 200
id grup
x A 1.0
B 3.0
y A 2.0
B NaN
dtype: float64
ValueError: dropna must be unspecified as the new implementation does not introduce rows of NA values. This argument will be removed in a future version of pandas.Mari kita telaah bagian-bagian pentingnya:
- Baris 12-17 (
stack): tabel 2x2 menjadi Series enam baris; label kolomBandungdanJakartapindah menjadi level index kedua, terlihat darist.index.namesyang berisi['bulan', 'kota']. - Baris 18-20 (
unstack):st.unstack()mengembalikan bentuk lebar awal;stack()laluunstack()merupakan pasangan bolak-balik yang saling membalikkan. - Baris 21-28 (
unstack(level="kota")): pada MultiIndex dua level, argumenlevelmenentukan level mana yang menjadi kolom; nama level ("kota") atau posisi angka sama-sama diterima. - Baris 30-32 (
fill_value): kombinasi Jakarta-Feb tidak ada di data, sehinggaunstack()mengisinyaNaNdanfill_value=0menggantinya. - Baris 33-46:
Nonepada sel kolom B bertahan sebagaiNaNsetelahstack(); implementasi baru pandas 3.0 tidak menghapus baris ber-NaN, dan argumendropnayang dulu mengaturnya sudah dihapus (galatnya dicetak di baris 42-46).
unstack(): Level Index Menjadi Kolom #
unstack() adalah kebalikan stack dan lazim dipakai setelah agregasi groupby ber-MultiIndex; hasil groupby(["kota", "bulan"]).sum() lebih mudah dibandingkan antar kolom setelah unstack(). Level terdalam menjadi kolom secara default, sehingga multi.unstack() tanpa argumen setara dengan multi.unstack(level=-1). Ketika kombinasi level tidak lengkap, sel yang tidak memiliki sumber diisi NaN, dan parameter fill_value menggantinya dengan nilai pilihan kita; pada data lengkap, argumen tersebut tidak berefek apa pun.
Perilaku Baru stack() pada pandas 3.0 #
Pandas 3.0 memakai implementasi stack baru yang membawa dua perubahan nyata. Pertama, baris ber-NaN tidak lagi dihapus saat menumpuk; tabel dengan sel kosong menghasilkan baris NaN yang terlihat seperti keluaran di atas, dan Anda membersihkannya sendiri dengan st.dropna() bila perlu. Kedua, parameter dropna dihapus sehingga stack(dropna=False) langsung memunculkan ValueError, dan argumen future_stack yang sempat menjadi jembatan di pandas 2.x kini usang; cukup panggil stack() tanpa argumen tambahan. Perubahan ini tercantum di whatsnew pandas 3.0
.
Referensi lengkapnya ada di user guide reshaping beserta dokumentasi method pandas.DataFrame.stack dan pandas.DataFrame.unstack . Dengan stack dan unstack di tangan, kita sudah menguasai seluruh alat pembentuk ulang; Chapter berikutnya merangkum kapan format lebar atau panjang lebih pantas dipakai.