Laporan bulanan yang kita bentuk dengan pivot() memang rapi dilihat, tetapi format lebar menyimpan informasi nama bulan di judul kolom, bukan di dalam data. Agregasi seperti groupby, pustaka visualisasi, dan sebagian besar alat statistik mengharapkan format panjang: satu kolom memuat kategori, satu kolom memuat nilainya. Method melt() melakukan kebalikan pivot, yaitu melelehkan banyak kolom nilai menjadi dua kolom: satu kolom nama variabel dan satu kolom nilai. Pada Chapter ini kita melelehkan tabel penjualan per bulan, mengatur nama kolom hasil, dan memilih bagian tabel yang dilelehkan.

Melelehkan Kolom Bulan Menjadi Baris #

Perhatikan pola argumen melt() secara berurutan: id_vars adalah kolom identitas yang tetap berdiri sebagai kolom, value_vars adalah kolom yang akan dilelehkan, var_name menamai kolom label, dan value_name menamai kolom nilai. File berikut melelehkan tiga kolom bulan menjadi sembilan baris data panjang.

python
import pandas as pd

penjualan = pd.DataFrame({
    "kota": ["Bandung", "Jakarta", "Surabaya"],
    "Jan": [120, 200, 150],
    "Feb": [135, 180, 160],
    "Mar": [140, 210, 155],
})

# melt: wide -> long
panjang = penjualan.melt(id_vars="kota", value_vars=["Jan", "Feb", "Mar"],
                         var_name="bulan", value_name="omzet")
print(panjang)
print()

# dtype hasil melt pada pandas 3.0
print(panjang.dtypes)
print()

# Hanya sebagian kolom yang dilelehkan
sebagian = penjualan.melt(id_vars="kota", value_vars=["Mar"],
                          var_name="bulan", value_name="omzet")
print(sebagian)
print()

# Dua kolom identifier dipertahankan sekaligus
detail = pd.DataFrame({
    "kota": ["Bandung", "Jakarta"],
    "produk": ["Kopi", "Kopi"],
    "Jan": [60, 100],
    "Feb": [70, 95],
})
print(detail.melt(id_vars=["kota", "produk"], var_name="bulan",
                  value_name="omzet"))

Output yang Dihasilkan:

text
       kota bulan  omzet
0   Bandung   Jan    120
1   Jakarta   Jan    200
2  Surabaya   Jan    150
3   Bandung   Feb    135
4   Jakarta   Feb    180
5  Surabaya   Feb    160
6   Bandung   Mar    140
7   Jakarta   Mar    210
8  Surabaya   Mar    155

kota       str
bulan      str
omzet    int64
dtype: object

       kota bulan  omzet
0   Bandung   Mar    140
1   Jakarta   Mar    210
2  Surabaya   Mar    155

      kota produk bulan  omzet
0  Bandung   Kopi   Jan     60
1  Jakarta   Kopi   Jan    100
2  Bandung   Kopi   Feb     70
3  Jakarta   Kopi   Feb     95

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 10-13 (melt): setiap sel angka menjadi satu baris; kolom Jan, Feb, Mar yang tadinya menampung data kini hanya menjadi nilai pada kolom bulan, dan angkanya pindah ke kolom omzet.
  2. Urutan baris: pandas melelehkan per kelompok variabel, sehingga semua baris Jan muncul lebih dulu, disusul Feb, lalu Mar; urutan ini mengikuti urutan value_vars.
  3. Baris 16-17 (dtypes): kota dan bulan bertipe str (dtype teks bawaan pandas 3.0), sedangkan omzet tetap int64; melt() tidak mengubah tipe nilai.
  4. Baris 20-23 (value_vars parsial): hanya kolom Mar yang dilelehkan, sehingga hasilnya tiga baris; kolom Jan dan Feb ditinggalkan.
  5. Baris 27-34 (id_vars list): dua kolom identitas kota dan produk dipertahankan sekaligus, pola standar ketika tabel punya hierarki lebih dari satu dimensi.

id_vars dan value_vars #

Kolom id_vars berperan sebagai pengenal baris; nilainya digandakan ke setiap baris hasil agar data tetap bisa dilacak asalnya. Bila value_vars tidak ditulis, pandas melelehkan semua kolom selain id_vars; jika keduanya dibiarkan kosong, seluruh kolom termasuk identitas ikut meleleh dan hasilnya hanya berisi kolom variable dan value default. Penamaan var_name dan value_name bersifat opsional, tetapi kita sangat disarankan memberinya nama bermakna seperti bulan dan omzet; label variable dan value bawaan jarang menjelaskan apa pun di laporan. Argumen ignore_index=False mempertahankan index asli tabel lebar bila Anda perlu menelusuri baris sumbernya.

Kapan melt() Dibutuhkan #

Tiga situasi paling sering menuntut format panjang. Pertama, agregasi lintas waktu: panjang.groupby("bulan")["omzet"].mean() berjalan langsung, sedangkan tabel lebar harus dirakit ulang dulu. Kedua, visualisasi: banyak library plotting menerima data panjang lalu memisahkan garis berdasarkan kolom kategori. Ketiga, penambahan dimensi baru: menambah kolom tahun pada tabel lebar berarti menambah kolom untuk setiap bulannya, sementara pada format panjang cukup menambah baris. Aturan praktisnya, simpan data mentah dalam format panjang dan bentuk format lebar hanya saat penyajian.

Dokumentasi user guide reshaping menempatkan melt sebagai kebalikan pivot, referensi pandas.DataFrame.melt merinci semua parameter, dan fungsi setara pandas.melt bekerja di level modul. Setelah menguasai pergeseran kolom-banyak-ke-baris ini, Chapter berikutnya memecah kolom berisi list menjadi baris dengan explode(), sebelum stack() dan unstack() menyempurnakan pergeseran pada level index.