Bagian 5 menunjukkan pergerakan; bagian ini mengukurnya. Pertanyaan Q1 dari Bagian 1 — seberapa bergejolak harga tiap komoditas — akhirnya kita jawab dengan tiga angka baku: rata-rata sebagai titik pusat, median sebagai pembanding yang tahan lonjakan, dan simpangan baku sebagai ukuran sebaran. Lalu, karena kelima komoditas berdagang di tingkat harga yang berbeda, kita menutup dengan satu ukuran yang membuat semuanya sebanding: koefisien variasi. Konsep tendensi sentral dan ukuran penyebaran sudah kita bahas pada Tendensi Sentral dan Ukuran Penyebaran ; di sini keduanya bekerja untuk data warung nyata.
Tiga Angka Per Komoditas #
Satu panggilan agg() merangkum lima statistik sekaligus untuk tiap komoditas:
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()
)
stat = df.groupby("komoditas")["harga_rata_ribu"].agg(["mean", "median", "std", "min", "max"])
print(stat.round(2).to_string())Output yang Dihasilkan:
mean median std min max
komoditas
ayam broiler 34.00 33.90 0.78 33.0 35.2
bawang merah 32.94 32.75 2.01 30.0 36.0
beras 13.25 13.25 0.16 13.0 13.5
cabai merah 50.25 43.00 14.53 38.0 78.0
gula pasir 17.65 17.65 0.12 17.5 17.8Tabel kecil ini menyimpan tiga temuan penting:
- Cabai merah: mean 50.25 jauh di atas median 43.00. Selisih sebesar itu terjadi karena dua pekan lonjakan (65.0 dan 78.0) menarik rata-rata ke atas, padahal mayoritas pekan harga cabai berkisar 38–44. Ketika mean dan median berpisah jauh, datanya miring — dan miringnya bersumber dari lonjakan M4–M5.
- Beras dan gula pasir: mean nyaris menyatu dengan median, std kecil. Beras 13.25/13.25 dan gula 17.65/17.65 — pola harga yang stabil dan simetris, tanpa kejutan.
mindanmaxmembingkai rentang penuh: cabai 38.0–78.0 (rentang 40.0 ribu!), beras 13.0–13.5 (rentang 0.5), gula 17.5–17.8 (rentang 0.3).
Menghitung Simpangan Baku dari Nol #
Sebelum memakai angka std di atas, mari kita pastikan tidak ada sulap di dalamnya. Rumus simpangan baku sampel:
s = akar( jumlah((x - rata_rata)^2) / (n - 1) )Tiap titik dihitung selisihnya dari rata-rata, dikuadratkan agar arah naik-turun tidak saling menghapus, dijumlahkan, dibagi n - 1 (koreksi sampel), lalu diakarkan agar kembali ke satuan rupiah. Kita hitung manual untuk beras dan bandingkan dengan hasil .std():
import math
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()
)
beras = df[df["komoditas"] == "beras"]["harga_rata_ribu"]
selisih_kuadrat = [(x - beras.mean()) ** 2 for x in beras]
std_manual = math.sqrt(sum(selisih_kuadrat) / (len(beras) - 1))
print(f"Rata-rata beras : {beras.mean():.4f}")
print(f"std beras (hitung manual) : {std_manual:.4f}")
print(f"std beras (metode .std()) : {beras.std():.4f}")Output yang Dihasilkan:
Rata-rata beras : 13.2500
std beras (hitung manual) : 0.1604
std beras (metode .std()) : 0.1604Kedua hasil identik sampai empat angka desimal, dan itu bukan kebetulan: metode .std() pandas memakai pembagi n - 1 (simpangan baku sampel) — sama dengan rumus manual kita. Kalau suatu saat Anda menemukan std yang “melenceng”, periksa dulu pembagi yang dipakai: n - 1 (sampel, ddof=1) atau n (populasi, ddof=0).
Koefisien Variasi untuk Membandingkan Antar Komoditas #
Sekarang persoalan adilnya perbandingan. Std cabai 14.53 tampak menumpulkan std beras 0.16 — tetapi cabai memang berdagang di kisaran 50 ribu sementara beras di 13 ribu. Komoditas mahal otomatis punya “ruang rupiah” lebih luas untuk berayun. Ukuran yang membandingkan sebaran relatif terhadap tingkat harganya sendiri adalah koefisien variasi:
cv = (std / mean) x 100%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()
)
stat = df.groupby("komoditas")["harga_rata_ribu"].agg(["mean", "std"])
stat["cv"] = stat["std"] / stat["mean"] * 100
print(stat.sort_values("cv", ascending=False).round(2).to_string())Output yang Dihasilkan:
mean std cv
komoditas
cabai merah 50.25 14.53 28.91
bawang merah 32.94 2.01 6.10
ayam broiler 34.00 0.78 2.29
beras 13.25 0.16 1.21
gula pasir 17.65 0.12 0.68Tabel ini adalah jawaban Q1 dan inti seluruh proyek:
| Komoditas | cv | Cara baca |
|---|---|---|
| cabai merah | 28.91% | Harga berayun hampir sepertiga tingkat rata-ratanya — paling bergejolak |
| bawang merah | 6.10% | Bergelombang sedang, naik-turun tapi terkendali |
| ayam broiler | 2.29% | Stabil secara mingguan (trennya kita bahas di Bagian 7) |
| beras | 1.21% | Nyaris datar |
| gula pasir | 0.68% | Paling tenang sepanjang periode |
Perhatikan bagaimana cv menata ulang dunia: ayam broiler yang std-nya 0.78 — lima kali std beras — ternyata sama-sama tergolong stabil karena ayunannya kecil dibanding tingkat harganya. Rincian penggunaan agg() per kolom ada di dokumentasi pandas tentang groupby
.
Ringkasan Bagian 6 #
Statistik lima angka memberi bentuk terukur: cabai merah paling bergejolak (std 14.53, cv 28.91%, mean terpisah 7.25 dari median), bawang merah menengah (cv 6.10%), sementara ayam, beras, dan gula pasir stabil dengan cv di bawah 2.5%. Verifikasi manual memastikan hitungan pandas transparan, dan cv membuat lima komoditas dengan tingkat harga berbeda bisa diperbandingkan secara adil.
Satu hal belum kita lihat: arah pergerakan. Std dan cv mengukur ayunan, tetapi tidak membedakan harga yang pulih (naik lalu turun, seperti cabai) dari harga yang merayap naik terus. Arah itulah yang kita kejar pada Bagian 7: Analisis Tren dan Musiman .