Data bersih sudah di tangan; sekarang kita mulai menjawab pertanyaan Q2 dari Bagian 1: kapan lonjakan harga terbesar terjadi dan seberapa besar. Alat kita tiga langkah: memutar data panjang menjadi tabel harga per pekan, menghitung perubahan persentase antar pekan, lalu membaca lonjakan cabai merah yang sudah tercium sejak Bagian 1. Semua blok pada bagian ini memakai resep pembersihan lima baris dari Bagian 4 sehingga setiap blok berdiri sendiri dan bisa disalin utuh.

Memutar Data Menjadi Tabel Harga #

Data panjang satu-baris-per-pengamatan enak dibersihkan, tetapi susah dibaca sebagai pergerakan waktu. Kita memutarnya: pekan menjadi baris, komoditas menjadi kolom, sehingga pergerakan harga tiap bahan terbaca sebaris demi sebaris:

python
import pandas as pd

# Resep pembersihan Bagian 4: 41 baris mentah menjadi 40 baris bersih.
df = pd.read_csv("../data/harga_komoditas.csv")
df = df.drop_duplicates(subset=["minggu", "komoditas"], keep="first").copy()
df["komoditas"] = df["komoditas"].str.strip().str.lower()
df["harga_rata_ribu"] = pd.to_numeric(df["harga_rata_ribu"], errors="coerce")
df = df.sort_values(["komoditas", "minggu"])
df["harga_rata_ribu"] = df.groupby("komoditas")["harga_rata_ribu"].transform(
    lambda s: s.interpolate()
)

pivot = df.pivot(index="minggu", columns="komoditas", values="harga_rata_ribu")
print(pivot)

Output yang Dihasilkan:

text
komoditas  ayam broiler  bawang merah  beras  cabai merah  gula pasir
minggu                                                               
M1                 33.0          30.0   13.0         38.0        17.5
M2                 33.5          34.0   13.2         40.0        17.6
M3                 33.2          31.0   13.1         42.0        17.5
M4                 33.8          36.0   13.3         65.0        17.7
M5                 34.0          33.0   13.2         78.0        17.6
M6                 34.5          32.5   13.4         55.0        17.8
M7                 34.8          32.0   13.3         44.0        17.7
M8                 35.2          35.0   13.5         40.0        17.8

Metode pivot() di atas menempatkan minggu sebagai indeks dan komoditas sebagai kolom; kolom harga terurut abjad sehingga lima komoditas tampil rapi berdampingan. Sekilas mata sudah menangkap pola: kolom cabai merah melompat dari 42.0 ke 65.0 dan 78.0 pada M4–M5 lalu menurun, sementara keempat kolom lainnya nyaris datar. Panduan lengkap tentang memutar dan menata ulang tabel ada di dokumentasi pandas tentang reshaping .

Perubahan Pekan-ke-Pekan Terbesar #

Tabel pivot enak dilihat, tetapi “terbesar” perlu dihitung, bukan dilihat. Kita hitung perubahan persentase tiap komoditas dari pekan sebelumnya dengan pct_change(), lalu urutkan berdasarkan besarnya — pakai nilai mutlak agar lonjakan naik dan turun sama-sama kelihatan:

python
import pandas as pd

df = pd.read_csv("../data/harga_komoditas.csv")
df = df.drop_duplicates(subset=["minggu", "komoditas"], keep="first").copy()
df["komoditas"] = df["komoditas"].str.strip().str.lower()
df["harga_rata_ribu"] = pd.to_numeric(df["harga_rata_ribu"], errors="coerce")
df = df.sort_values(["komoditas", "minggu"])
df["harga_rata_ribu"] = df.groupby("komoditas")["harga_rata_ribu"].transform(
    lambda s: s.interpolate()
)

perubahan = df.assign(
    perubahan_pct=df.groupby("komoditas")["harga_rata_ribu"].pct_change() * 100
).dropna(subset=["perubahan_pct"])

terbesar = perubahan.reindex(
    perubahan["perubahan_pct"].abs().sort_values(ascending=False).index
)
print(
    terbesar.head(5)[["minggu", "komoditas", "harga_rata_ribu", "perubahan_pct"]]
    .round(1)
    .to_string(index=False)
)

Output yang Dihasilkan:

text
minggu    komoditas  harga_rata_ribu  perubahan_pct
    M4  cabai merah             65.0           54.8
    M6  cabai merah             55.0          -29.5
    M5  cabai merah             78.0           20.0
    M7  cabai merah             44.0          -20.0
    M4 bawang merah             36.0           16.1

Mari kita baca tabel tersebut:

  1. Lima perubahan terbesar, empat di antaranya cabai merah: +54.8% (M3 → M4), −29.5% (M5 → M6), +20.0% (M4 → M5), −20.0% (M6 → M7). Posisi kelima baru disandang bawang merah dengan +16.1%.
  2. Kolom harga_rata_ribu adalah harga pekan tersebut: baris pertama berarti pada M4 cabai dihargai 65.0, naik 54.8% dari 42.0 pada M3 — karena pct_change() selalu membandingkan dengan pekan sebelumnya.
  3. groupby("komoditas") menjaga batas perbandingan: tanpa pengelompokan, baris pertama tiap komoditas akan dibandingkan dengan komoditas sebelumnya di tabel — kesalahan klasik pada data panel seperti ini.

Perubahan sebesar +54.8% dalam satu pekan adalah angka yang menjelaskan mengapa keluhan Bu Warni terasa begitu nyata: separuh lagi biaya cabai muncul dalam tujuh hari.

Membaca Lonjakan Cabai Merah M4-M5 #

Lonjakan cabai bukan peristiwa sesaat; bentuknya penuh — naik dua pekan beruntun, lalu turun bertahap tiga pekan. Blok berikut merangkum keseluruhannya dari kolom pivot:

python
import pandas as pd

df = pd.read_csv("../data/harga_komoditas.csv")
df = df.drop_duplicates(subset=["minggu", "komoditas"], keep="first").copy()
df["komoditas"] = df["komoditas"].str.strip().str.lower()
df["harga_rata_ribu"] = pd.to_numeric(df["harga_rata_ribu"], errors="coerce")
df = df.sort_values(["komoditas", "minggu"])
df["harga_rata_ribu"] = df.groupby("komoditas")["harga_rata_ribu"].transform(
    lambda s: s.interpolate()
)
pivot = df.pivot(index="minggu", columns="komoditas", values="harga_rata_ribu")
cabai = pivot["cabai merah"]

print("Harga cabai merah per pekan (ribu rupiah per kg):")
print(cabai.to_string())
print()
naik = (cabai["M5"] / cabai["M3"] - 1) * 100
pulih = (cabai["M8"] / cabai["M5"] - 1) * 100
print(f"M3 -> M5 : {cabai['M3']:.1f} -> {cabai['M5']:.1f} (naik {naik:.1f}%)")
print(f"M5 -> M8 : {cabai['M5']:.1f} -> {cabai['M8']:.1f} (turun {abs(pulih):.1f}%)")
print(f"Puncak M5 = {cabai['M5'] / cabai['M1']:.2f} kali harga M1 ({cabai['M1']:.1f})")

Output yang Dihasilkan:

text
Harga cabai merah per pekan (ribu rupiah per kg):
minggu
M1    38.0
M2    40.0
M3    42.0
M4    65.0
M5    78.0
M6    55.0
M7    44.0
M8    40.0

M3 -> M5 : 42.0 -> 78.0 (naik 85.7%)
M5 -> M8 : 78.0 -> 40.0 (turun 48.7%)
Puncak M5 = 2.05 kali harga M1 (38.0)

Tiga angka penutup bagian ini: kenaikan dua pekan berturut-turut M3 → M5 mencapai 85.7%; pemulihan M5 → M8 memotong hampir separuh harga (turun 48.7%); dan puncak M5 berdiri di 2.05 kali harga awal periode. Bentuk “bukit” seperti ini — naik cepat, turun bertahap — adalah tanda gejolak pasokan musiman, bukan kenaikan harga struktural. Dugaan itu kita perkuat dengan konteks musim hujan pada Bagian 7.

Ringkasan Bagian 5 #

Pivot mengubah data panjang menjadi tabel harga per pekan; pct_change() per komoditas menemukan bahwa empat dari lima perubahan terbesar milik cabai merah, dengan lonjakan +54.8% pada M3 → M4 dan puncak 78.0 pada M5; harga kemudian pulih ke 40.0 pada M8. Pertanyaan Q2 terjawab: lonjakan terbesar terjadi pada M4–M5 dan besarnya dua kali lipat harga normal.

Berapa “normal” itu? Pertanyaan berikutnya menuntut ukuran pemusatan dan penyebaran yang adil untuk semua komoditas — pekerjaan Bagian 6: Analisis Statistik Harga .