Level harga seperti “beras Rp15 000” nyaris tidak bercerita; analis pasar justru hidup dari perubahannya — berapa rupiah naiknya, berapa persen turunnya, dan sebesar apa fluktuasinya. Bagian ini menghitung tiga besaran itu langsung dari array harga yang dibangun pada Bagian 1: Menyiapkan Data Harga: perubahan persentase harian dari perbandingan array bergeser, perubahan rupiah dari np.diff, serta volatilitas dari simpangan baku perubahan persentase.
Seluruh perhitungan berjalan pada dua dimensi sekaligus (360 hari × 3 komoditas) tanpa satu pun loop eksplisit. Pola yang dipakai adalah vektorisasi biasa — pasangan slice a[1:] dan a[:-1] dari Chapter Slicing Array, agregasi axis=0 dari Chapter Operasi Berdasarkan Axis.
Perubahan Persentase Harian #
Perubahan persentase hari ke t didefinisikan sebagai harga[t]/harga[t-1] - 1. Padanan vektorisasinya menumpuk dua slice: harga[1:] (hari kedua sampai terakhir) dibagi harga[:-1] (hari pertama sampai kedua terakhir):
import numpy as np
# Pembangun deret harga 2025 (identik dengan Bagian 1).
rng = np.random.default_rng(42)
awal = np.array([15000.0, 45000.0, 18000.0])
drift = np.array([0.0003, 0.0012, 0.0004])
sigma = np.array([0.006, 0.030, 0.010])
musim = 1 - np.array([0.01, 0.15, 0.03]) * np.cos(2 * np.pi * np.arange(360) / 360)[:, None]
guncangan = drift + rng.normal(0.0, sigma, (360, 3))
harga = awal * np.cumprod(1 + guncangan, axis=0) * musim
pct = harga[1:] / harga[:-1] - 1
print("shape:", pct.shape)
print(np.round(pct[:3], 4))Output yang Dihasilkan:
shape: (359, 3)
[[ 0.0059 -0.0573 -0.0126]
[ 0.0011 -0.0082 0.0002]
[-0.0048 0.0277 0.0082]]Mekanismenya:
harga[1:] / harga[:-1]: dua view berukuran 359 × 3 dibagi per elemen; baris ke-ihasilnya adalah rasio harga harii+1terhadap harii— satu hari lebih pendek daripada deret asal, karena hari pertama tidak punya pendahulu.- 1: mengubah rasio menjadi fraksi perubahan;0.0059berarti beras naik 0.59% pada hari kedua, sedangkan cabai turun 5.73% pada hari yang sama — lonjakan pembuka yang khas komoditas bervolatilitas tinggi.np.round(pct[:3], 4): tiga baris pertama ditampilkan empat desimal; fraksi ini nanti dikalikan 100 jika ingin ditulis sebagai persen.
Perhatikan bahwa pct bukan sekadar angka baru: ia menggabungkan efek drift, guncangan, dan rasio faktor musiman antar dua hari berurutan. Deret inilah bahan mentah statistik sisa bagian ini.
Perubahan Rupiah dengan np.diff #
Untuk beberapa keperluan — margin pedagang, anggaran rumah tangga — perubahan dalam rupiah lebih bermakna. np.diff menghitung selisih berurutan di sepanjang axis yang dipilih, dan bersama argmax/argmin (Chapter min, max, argmin, dan argmax) kita bisa menemukan hari kenaikan serta penurunan terbesar tiap komoditas:
import numpy as np
# Pembangun deret harga 2025 (identik dengan Bagian 1).
rng = np.random.default_rng(42)
awal = np.array([15000.0, 45000.0, 18000.0])
drift = np.array([0.0003, 0.0012, 0.0004])
sigma = np.array([0.006, 0.030, 0.010])
musim = 1 - np.array([0.01, 0.15, 0.03]) * np.cos(2 * np.pi * np.arange(360) / 360)[:, None]
guncangan = drift + rng.normal(0.0, sigma, (360, 3))
harga = awal * np.cumprod(1 + guncangan, axis=0) * musim
selisih = np.diff(harga, axis=0)
print("shape:", selisih.shape)
tanggal = np.arange(np.datetime64("2025-01-01"), np.datetime64("2025-12-27"))
nama = np.array(["beras", "cabai", "minyak goreng"])
i_naik = np.argmax(selisih, axis=0)
i_turun = np.argmin(selisih, axis=0)
for k in range(3):
i, j = i_naik[k], i_turun[k]
print(f"{nama[k]:<14} naik {tanggal[i + 1]} {selisih[i, k]:+10.2f}")
print(f"{nama[k]:<14} turun {tanggal[j + 1]} {selisih[j, k]:+10.2f}")Output yang Dihasilkan:
shape: (359, 3)
beras naik 2025-10-10 +300.04
beras turun 2025-06-18 -280.07
cabai naik 2025-02-16 +3043.55
cabai turun 2025-11-13 -3744.06
minyak goreng naik 2025-06-09 +540.76
minyak goreng turun 2025-11-12 -532.10Yang perlu diperhatikan:
np.diff(harga, axis=0): selisih antar baris berurutan; hasilnya 359 × 3, satu baris lebih pendek, sama sepertipct.np.argmax(selisih, axis=0): mencari posisi nilai maksimum per kolom, sehingga satu indeks keluar untuk tiap komoditas tanpa loop.tanggal[i + 1]: baris ke-idariselisihadalah perubahan dari hariike harii+1, maka tanggal peristiwanya adalahtanggal[i + 1]— rincian satu-per satu ini paling sering keliru saat manual.- Kenaikan cabai Rp3 043,55 pada 16 Februari: setara sekitar +7.5% dalam sehari; pada komoditas yang harganya 45 ribuan, guncangan harian 3% memang mudah menghasilkan lompatan ribuan rupiah.
Volatilitas dan Arah Harian #
Volatilitas harian didefinisikan sebagai simpangan baku pct per kolom (Chapter Variance dan Standard Deviation). Pasangannya adalah statistik arah: berapa hari harga naik dan berapa hari turun, yang dihitung dari mask boolean (Chapter Counting dan Frekuensi):
import numpy as np
# Pembangun deret harga 2025 (identik dengan Bagian 1).
rng = np.random.default_rng(42)
awal = np.array([15000.0, 45000.0, 18000.0])
drift = np.array([0.0003, 0.0012, 0.0004])
sigma = np.array([0.006, 0.030, 0.010])
musim = 1 - np.array([0.01, 0.15, 0.03]) * np.cos(2 * np.pi * np.arange(360) / 360)[:, None]
guncangan = drift + rng.normal(0.0, sigma, (360, 3))
harga = awal * np.cumprod(1 + guncangan, axis=0) * musim
pct = harga[1:] / harga[:-1] - 1
vol = pct.std(axis=0, ddof=1)
nama = np.array(["beras", "cabai", "minyak goreng"])
for k in range(3):
print(f"{nama[k]:<14} vol {vol[k]:.4f} hari naik {np.sum(pct[:, k] > 0):3d} hari turun {np.sum(pct[:, k] < 0):3d}")Output yang Dihasilkan:
beras vol 0.0062 hari naik 186 hari turun 173
cabai vol 0.0290 hari naik 179 hari turun 180
minyak goreng vol 0.0096 hari naik 187 hari turun 172Pembacaan hasilnya:
pct.std(axis=0, ddof=1): simpangan baku dengan pembagin - 1— estimasi tak biasa dari 359 sampel;ddof=0bawaan akan memberi angka sedikit lebih kecil.- Volatilitas cabai 0.0290: hampir lima kali volatilitas beras (0.0062) — angka ringkas yang menjelaskan mengapa harga cabai paling sering menjadi berita.
np.sum(pct[:, k] > 0): mask boolean dijumlahkan per komoditas; hari naik dan turun hampir berimbang (sekitar 50:50) — arah rata-rata memang ditentukandriftyang kecil, bukan oleh kecenderungan harian.
Tiga besaran di bagian ini — pct, selisih, dan vol — tersimpan rapi sebagai array dan siap dipakai Bagian 3: Menganalisis Statistik. Dalam struktur proyek, seluruhnya kita kemas sebagai src/perubahan.py dengan satu fungsi per besaran.