melt: Lebar ke Panjang

Mengubah data lebar ke format panjang dengan melt dan id_vars.

Daftar isi

Fungsi melt mengubah tabel lebar menjadi tabel panjang, yaitu kebalikan arah dari pivot. Topik ini membahas parameter id_vars, var_name, dan value_name, pemeriksaan hasil dengan equals, pemilihan subset kolom dengan value_vars, serta kesalahan umum ketika id_vars terlupa. Data yang digunakan adalah tabel lebar mini hasil pivot, sehingga hubungan bolak-balik kedua fungsi dapat diverifikasi secara eksak.

melt mengembalikan lebar ke panjang#

Fungsi melt mencairkan kolom kategori menjadi baris, sehingga tabel yang semula melebar kembali memanjang dengan satu baris per pengamatan. Bangun ulang tabel lebar mini berikut sebagai titik awal, lalu simpan data panjangnya untuk potongan-potongan berikutnya.

python Tabel lebar mini hasil pivot
import pandas as pd

panjang = pd.DataFrame({
    "waktu": ["08:00", "08:00", "08:00", "08:15", "08:15", "08:15"],
    "ruang": ["Lab A", "Lab B", "Ruang Arsip", "Lab A", "Lab B", "Ruang Arsip"],
    "suhu_c": [23.5, 22.8, 21.0, 23.9, 22.6, 20.9],
})
mini_lebar = panjang.pivot(index="waktu", columns="ruang", values="suhu_c")
panjang.to_csv("mini_log.csv", index=False)  # disimpan agar blok berikutnya cukup membaca berkas ini
print(mini_lebar)
text Keluaran
ruang  Lab A  Lab B  Ruang Arsip
waktu
08:00   23.5   22.8         21.0
08:15   23.9   22.6         20.9

melt dipanggil pada tabel datar, sehingga indeks waktu dilepas lebih dahulu dengan reset_index. Tiga parameter utamanya menetapkan bentuk hasil, yaitu id_vars yang menjaga kolom identitas tetap menjadi kolom, var_name yang menamai kolom kategori baru, dan value_name yang menamai kolom nilai.

python melt dari lebar kembali ke panjang
import pandas as pd

panjang = pd.read_csv("mini_log.csv")
mini_lebar = panjang.pivot(index="waktu", columns="ruang", values="suhu_c")
lebar_reset = mini_lebar.reset_index()
meleleh = pd.melt(lebar_reset, id_vars="waktu", var_name="ruang", value_name="suhu_c")
print(meleleh)
text Keluaran
   waktu        ruang  suhu_c
0  08:00        Lab A    23.5
1  08:15        Lab A    23.9
2  08:00        Lab B    22.8
3  08:15        Lab B    22.6
4  08:00  Ruang Arsip    21.0
5  08:15  Ruang Arsip    20.9

Hasilnya enam baris, sesuai jumlah sel pada tabel lebar, dengan kolom ruang dan suhu_c tersusun sebagai data biasa. Urutan barisnya dikelompokkan menurut kolom asal, yaitu semua baris Lab A dahulu, kemudian Lab B, lalu Ruang Arsip, sehingga urutannya berbeda dari tabel panjang semula padahal isinya sama persis. Urutan ini bukan keanehan, melainkan konsekuensi cara melt menumpuk kolom satu per satu.

Memeriksa kebalikan pivot dengan equals#

Klaim bahwa melt adalah kebalikan pivot dapat diverifikasi dengan equals, yaitu perbandingan yang menuntut isi, tipe, urutan kolom, dan urutan baris yang sama. Karena urutan baris hasil melt mengikuti kolom asal, kedua tabel diurutkan menurut ruang dan waktu sebelum dibandingkan.

python Verifikasi equals setelah pengurutan
import pandas as pd

panjang = pd.read_csv("mini_log.csv")
meleleh = pd.melt(
    panjang.pivot(index="waktu", columns="ruang", values="suhu_c").reset_index(),
    id_vars="waktu", var_name="ruang", value_name="suhu_c",
)
kembali = meleleh.sort_values(["ruang", "waktu"]).reset_index(drop=True)
asli = panjang.sort_values(["ruang", "waktu"]).reset_index(drop=True)
print(kembali.equals(asli))
text Keluaran
True

Nilai True menegaskan bahwa tidak ada data yang hilang maupun berubah tipe selama dua kali perubahan bentuk itu. Pemeriksaan semacam ini layak dijadikan kebiasaan setiap kali tabel dimanipulasi berantai, karena kesalahan bentuk paling sulit terlihat pada tabel yang tampak benar. Tanpa pengurutan terlebih dahulu, equals mengembalikan False semata karena urutan baris, bukan karena isinya salah.

Memilih subset kolom dengan value_vars#

Parameter value_vars membatasi kolom yang dilelehkan, sehingga laporan yang hanya membutuhkan sebagian kategori tidak perlu menghapus baris setelahnya. Kolom yang tidak disebut tetap utuh pada tabel sumber, dan kolom identitas dari id_vars tetap mengikuti setiap baris hasil.

python melt pada subset kolom Lab A dan Lab B
import pandas as pd

lebar_reset = pd.read_csv("mini_log.csv").pivot(
    index="waktu", columns="ruang", values="suhu_c",
).reset_index()
subset = pd.melt(
    lebar_reset, id_vars="waktu", value_vars=["Lab A", "Lab B"],
    var_name="ruang", value_name="suhu_c",
)
print(subset)
text Keluaran
   waktu  ruang  suhu_c
0  08:00  Lab A    23.5
1  08:15  Lab A    23.9
2  08:00  Lab B    22.8
3  08:15  Lab B    22.6

Hasilnya empat baris, karena dua kolom kategori dikalikan dua titik waktu, dan Ruang Arsip sama sekali tidak muncul. Apabila value_vars tidak ditetapkan, seluruh kolom selain id_vars dilelehkan, dan itulah perilaku default yang menimbulkan kesalahan pada bagian berikut.

Kesalahan umum#

Kesalahan paling lazim adalah memanggil melt tanpa id_vars, sehingga semua kolom termasuk kolom identitas ikut meleleh dan tabel kehilangan makna barisnya. Jalankan demo berikut untuk melihat bentuk rusaknya.

python melt tanpa id_vars membuat waktu ikut meleleh
import pandas as pd

lebar_reset = pd.read_csv("mini_log.csv").pivot(
    index="waktu", columns="ruang", values="suhu_c",
).reset_index()
semua = pd.melt(lebar_reset)
print(semua.shape)
print(semua.head(6))
text Keluaran
(8, 2)
   ruang  value
0  waktu  08:00
1  waktu  08:15
2  Lab A   23.5
3  Lab A   23.9
4  Lab B   22.8
5  Lab B   22.6

Tabel yang tadinya empat kolom kini menjadi delapan baris berisi pasangan label dan nilai, dan waktu bercampur dengan nama ruang pada kolom yang sama. Kolom labelnya pun berlabel ruang karena mewarisi nama level kolom hasil pivot, bukan karena isinya benar-benar ruang. Perbaikannya sederhana, yaitu tetapkan id_vars pada setiap panggilan melt agar kolom identitas terjaga, lalu beri nama hasil dengan var_name dan value_name agar tabel panjangnya langsung terbaca.

Ringkasan#

  • melt memanjangkan tabel dengan mencairkan kolom kategori menjadi baris, sebagai kebalikan arah pivot.
  • id_vars menjaga kolom identitas, sedangkan var_name dan value_name menamai kolom hasil.
  • value_vars membatasi kolom yang dilelehkan tanpa mengubah tabel sumber.
  • equals setelah pengurutan memverifikasi kebalikan pivot secara eksak, termasuk tipe dan urutan kolom.

Referensi#