Penjualan harian yang dipola mingguan terlihat bergerigi: hari Senin selalu turun dan hari Minggu selalu naik, padahal tren bulanannya sebenarnya stabil naik. Series.rolling() mengatasi ini dengan menggeser sebuah jendela (window) sepanjang data dan menghitung satu statistik per jendela — teknik yang dikenal sebagai moving average ketika statistiknya adalah rata-rata. Chapter ini membangun rata-rata bergerak 7 hari pada dataset penjualan Toko Sembako Berkah, mengatur perilaku baris awal dengan min_periods, menggeser posisi label dengan center, lalu menghitung statistik bergerak lain lewat agg.

Rata-rata Bergerak 7 Hari #

Baris 8 memanggil df["penjualan"].rolling(window=7).mean() dan menugaskan hasilnya ke kolom baru ma7. Blok output pertama memperlihatkan perilaku khas rolling: enam baris pertama bernilai NaN karena jendela 7 hari belum penuh, lalu mulai 7 Januari kolom terisi 210.0. Angka 210 bukan kebetulan — rata-rata satu siklus minggu penuh (150 sampai 270 dengan selisih tetap 20) selalu 210, sehingga di bulan Januari yang tanpa kenaikan bulanan, kolom ma7 stabil di 210.0. Saat Februari menaikkan penjualan 30 unit, nilai ma7 akan naik bertahap mengikuti pergeseran jendela.

python
import pandas as pd

tanggal = pd.date_range("2026-01-01", "2026-03-31", freq="D", name="tanggal")
penjualan = [150 + t.dayofweek * 20 + (t.month - 1) * 30 for t in tanggal]
df = pd.DataFrame({"penjualan": penjualan}, index=tanggal)

# Rata-rata bergerak 7 hari disimpan sebagai kolom baru ma7
df["ma7"] = df["penjualan"].rolling(window=7).mean()
print(df.head(9))

# min_periods=1: baris awal tetap terhitung meski window belum penuh
df["ma7_awal"] = df["penjualan"].rolling(window=7, min_periods=1).mean().round(2)
print()
print(df.head(3))

# center=True: nilai window ditempel di tengah jendela, bukan di ujung kanan
tengah = df["penjualan"].rolling(window=7, center=True).mean()
print()
print(tengah.head(5))

# Statistik bergerak lain lewat agg: standar deviasi dan maksimum
statistik = df["penjualan"].rolling(window=7).agg(["std", "max"]).round(2)
print()
print(statistik.head(8))

Output yang Dihasilkan:

text
            penjualan    ma7
tanggal                     
2026-01-01        210    NaN
2026-01-02        230    NaN
2026-01-03        250    NaN
2026-01-04        270    NaN
2026-01-05        150    NaN
2026-01-06        170    NaN
2026-01-07        190  210.0
2026-01-08        210  210.0
2026-01-09        230  210.0

            penjualan  ma7  ma7_awal
tanggal                             
2026-01-01        210  NaN     210.0
2026-01-02        230  NaN     220.0
2026-01-03        250  NaN     230.0

tanggal
2026-01-01      NaN
2026-01-02      NaN
2026-01-03      NaN
2026-01-04    210.0
2026-01-05    210.0
Freq: D, Name: penjualan, dtype: float64

             std    max
tanggal                
2026-01-01   NaN    NaN
2026-01-02   NaN    NaN
2026-01-03   NaN    NaN
2026-01-04   NaN    NaN
2026-01-05   NaN    NaN
2026-01-06   NaN    NaN
2026-01-07  43.2  270.0
2026-01-08  43.2  270.0

Mari kita telaah bagian-bagian penting skrip di atas:

  1. Baris 8-9: rolling(window=7).mean() menghasilkan kolom ma7; enam NaN pertama lalu 210.0.
  2. Baris 12-14: min_periods=1 membuat baris awal tetap terhitung; hasilnya 210.0, 220.0, 230.0.
  3. Baris 17-19: center=True menggeser label hasil ke tengah jendela; nilai 210.0 pertama kini muncul di 2026-01-04.
  4. Baris 22-24: agg(["std", "max"]) menghitung dua statistik bergerak sekaligus.

Setiap baris hasil adalah rata-rata dari 7 nilai yang berakhir pada tanggal label tersebut. Baris 7 Januari merata-ratakan 1-7 Januari, baris 8 Januari merata-ratakan 2-8 Januari, dan seterusnya — jendela bergeser satu baris per langkah.

Menangani Baris Awal dengan min_periods #

NaN di awal kolom ma7 adalah perilaku default yang jujur: pandas tidak menghitung rata-rata dari data yang kurang dari 7 nilai. Argumen min_periods melonggarkan aturan itu — min_periods=1 pada baris 12 memerintahkan perhitungan begitu ada satu nilai saja. Hasilnya di blok kedua: 210.0 pada 1 Januari (rata-rata satu nilai), 220.0 pada 2 Januari (rata-rata 210 dan 230), dan seterusnya naik menuju 210.0 yang stabil. Nilai awal ini bias, tetapi berguna saat kolom hasil dibutuhkan tanpa lubang, misalnya untuk input visualisasi.

Menyelaraskan Posisi Window dengan center #

Secara bawaan, hasil jendela ditempel di ujung kanan jendela: nilai 1-7 Januari dilabeli 7 Januari. Argumen center=True pada baris 17 memindahkan label ke tengah jendela, sehingga rata-rata 1-7 Januari kini dilabeli 4 Januari — terlihat di blok ketiga yang mulai terisi pada 2026-01-04 dengan tiga NaN di depannya. Center membuat kurva bergerak sejajar dengan kejadian yang diringkasnya, sehingga lazim dipakai untuk visualisasi tren. Untuk laporan yang menekankan nilai terakhir yang diketahui (misalnya sinyal perdagangan), posisi default tanpa center justru yang benar karena tidak memakai masa depan.

Statistik Bergerak Lainnya #

Rata-rata bukan satu-satunya statistik bergerak. Baris 22 memakai agg(["std", "max"]) dan menghasilkan dua kolom sekaligus: standar deviasi jendela (43.2 untuk siklus mingguan penuh) dan nilai maksimum jendela (270.0 selama pola Januari belum berubah). Fungsi apa pun yang dipakai pada agregasi biasa — sum(), min(), median(), bahkan fungsi kustom — dapat diterapkan pada objek rolling. Ringkasan parameter yang menentukan perilaku jendela:

ParameterPeranNilai bawaan
windowUkuran jendela: jumlah baris, atau string durasi seperti "7D" saat index datetimewajib diisi
min_periodsJumlah nilai minimum dalam jendela agar hasil dihitung, sisanya NaNsama dengan window
centerMenempel hasil di tengah jendela, bukan di ujung kananFalse

Dokumentasi resmi yang relevan: pandas.DataFrame.rolling , pandas.Series.rolling , dan User Guide: Time series .

Rolling memakai jendela berukuran tetap: statistik Januari tidak pernah terpengaruh data Maret. Chapter berikutnya melengkapi teknik ini dengan jendela yang tumbuh terus dari awal data — expanding window — yang berguna untuk statistik kumulatif.