Analisis Time Series dengan Pandas 3.0: Resample, Rolling Window, dan Visualisasi

Panduan praktis analisis time series dengan pandas 3.0 — mulai dari resampling, rolling window, EWMA, hingga visualisasi. Semua contoh kode sudah disesuaikan dengan offset alias terbaru pandas 3.0.1.

Mengapa Analisis Time Series Masih Jadi Skill Wajib di 2026?

Kalau kamu bekerja dengan data — entah itu harga saham, sensor IoT, data cuaca, atau bahkan log traffic website — kemungkinan besar kamu sudah pernah (atau akan segera) berhadapan dengan data deret waktu. Jujur saja, kemampuan menganalisis pola, tren, dan anomali dalam data temporal itu bukan sekadar nice-to-have lagi. Di 2026, ini sudah jadi kebutuhan dasar buat data scientist maupun data engineer.

Nah, kabar baiknya: dengan rilisnya pandas 3.0 di awal 2026, toolkit Python untuk time series makin matang. Dan di panduan ini, kita akan bahas semuanya — dari dasar sampai teknik lanjutan. Semua contoh kode sudah disesuaikan dengan pandas 3.0.1 dan offset alias terbarunya.

Yuk, langsung mulai.

Persiapan Lingkungan Kerja

Instalasi Library yang Diperlukan

Sebelum ngapa-ngapain, pastikan dulu kamu sudah instal pandas versi terbaru beserta library pendukungnya. Jalankan ini di terminal:

pip install pandas==3.0.1 matplotlib seaborn numpy

Lalu import semua yang kita butuhkan:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns

# Verifikasi versi pandas
print(f"Pandas version: {pd.__version__}")
# Output: Pandas version: 3.0.1

# Konfigurasi tampilan
pd.set_option('display.max_rows', 20)
sns.set_style('whitegrid')
plt.rcParams['figure.figsize'] = (14, 5)

Membuat Dataset Contoh

Untuk tutorial ini, kita bikin dataset sintetis yang mensimulasikan data penjualan harian selama dua tahun. Saya sering pakai pendekatan ini saat bikin prototipe — jauh lebih mudah daripada harus cari dataset yang pas:

# Membuat DatetimeIndex untuk 2 tahun data harian
tanggal = pd.date_range(start='2024-01-01', end='2025-12-31', freq='D')

# Simulasi data penjualan dengan tren, musiman, dan noise
np.random.seed(42)
n = len(tanggal)
tren = np.linspace(100, 180, n)  # tren naik
musiman = 25 * np.sin(2 * np.pi * np.arange(n) / 365.25)  # siklus tahunan
mingguan = 10 * np.sin(2 * np.pi * np.arange(n) / 7)  # siklus mingguan
noise = np.random.normal(0, 8, n)

penjualan = tren + musiman + mingguan + noise

df = pd.DataFrame({
    'tanggal': tanggal,
    'penjualan': np.round(penjualan, 2),
    'kategori': np.random.choice(['Elektronik', 'Fashion', 'Makanan'], n)
})

df['tanggal'] = pd.to_datetime(df['tanggal'])
df = df.set_index('tanggal')

print(df.head(10))
print(f"\nJumlah baris: {len(df)}")
print(f"Rentang waktu: {df.index.min()} s/d {df.index.max()}")

Memahami DatetimeIndex di Pandas

Ini fondasi dari segala analisis time series di pandas: DatetimeIndex. Tanpa index bertipe datetime, kamu nggak bisa pakai fitur-fitur keren pandas seperti resample(), slicing berbasis tanggal, dan offset operations. Jadi pastikan ini langkah pertama kamu setiap kali ngerjain data time series.

Konversi dan Pembuatan DatetimeIndex

# Cara 1: Konversi kolom string ke datetime
df_raw = pd.read_csv('data_penjualan.csv')
df_raw['tanggal'] = pd.to_datetime(df_raw['tanggal'], format='%Y-%m-%d')
df_raw = df_raw.set_index('tanggal')

# Cara 2: Parse saat membaca CSV (ini cara favorit saya)
df_raw = pd.read_csv('data_penjualan.csv', parse_dates=['tanggal'], index_col='tanggal')

# Cara 3: Membuat DatetimeIndex dari awal
idx = pd.date_range(start='2024-01-01', periods=365, freq='D')

# Verifikasi tipe index
print(type(df.index))  # 
print(df.index.dtype)   # datetime64[ns]

Slicing Berbasis Tanggal

Salah satu hal yang bikin saya jatuh cinta sama DatetimeIndex adalah kemampuan slicing-nya yang super intuitif:

# Ambil data tahun 2024 saja
df_2024 = df.loc['2024']
print(f"Data 2024: {len(df_2024)} baris")

# Ambil data kuartal pertama 2025
df_q1_2025 = df.loc['2025-01':'2025-03']
print(f"Q1 2025: {len(df_q1_2025)} baris")

# Ambil data bulan tertentu
df_juni = df.loc['2024-06']
print(f"Juni 2024: {len(df_juni)} baris")

Cukup tulis string tanggal, dan pandas otomatis menerjemahkannya. Simpel banget, kan?

Mengakses Komponen Waktu

# Ekstrak komponen waktu dari index
df['tahun'] = df.index.year
df['bulan'] = df.index.month
df['hari_dalam_minggu'] = df.index.dayofweek  # 0=Senin, 6=Minggu
df['nama_hari'] = df.index.day_name()
df['kuartal'] = df.index.quarter

print(df[['penjualan', 'tahun', 'bulan', 'nama_hari']].head())

Resampling: Mengubah Frekuensi Data Time Series

Oke, sekarang kita masuk ke salah satu fitur paling powerful di pandas untuk time series: resampling. Sederhananya, resampling itu mengubah frekuensi data. Kalau kamu pernah pakai groupby(), konsepnya mirip — tapi khusus untuk data berbasis waktu.

Ada dua jenis resampling:

  • Downsampling — dari frekuensi tinggi ke rendah (misalnya harian ke bulanan). Data diagregasi.
  • Upsampling — dari frekuensi rendah ke tinggi (misalnya bulanan ke harian). Ini butuh metode pengisian data karena kita "menciptakan" titik data baru.

Offset Alias Terbaru di Pandas 3.0

Ini penting banget, terutama kalau kamu baru upgrade ke pandas 3.0. Beberapa offset alias lama sudah dihapus total — bukan cuma deprecated, tapi benar-benar error kalau dipakai:

# Offset Alias Pandas 3.0 (yang benar)
# 'ME'  = Month End (sebelumnya 'M')
# 'MS'  = Month Start
# 'YE'  = Year End (sebelumnya 'Y' atau 'A')
# 'YS'  = Year Start
# 'QE'  = Quarter End (sebelumnya 'Q')
# 'QS'  = Quarter Start
# 'BME' = Business Month End (sebelumnya 'BM')
# 'BYE' = Business Year End (sebelumnya 'BY')
# 'W'   = Weekly
# 'D'   = Daily
# 'h'   = Hourly (sebelumnya 'H')
# 'min' = Minutely (sebelumnya 'T')
# 's'   = Secondly (sebelumnya 'S')

# PENTING: Alias lama seperti 'M', 'Y', 'Q', 'H', 'T', 'S'
# sudah DIHAPUS di pandas 3.0. Gunakan alias baru!

Saya sendiri pernah kena error ini saat pertama kali upgrade. Lumayan bikin bingung kalau kamu nggak tahu perubahannya.

Downsampling: Dari Data Harian ke Bulanan

# Resampling harian ke bulanan — rata-rata penjualan per bulan
bulanan_mean = df['penjualan'].resample('ME').mean()
print("Rata-rata penjualan bulanan:")
print(bulanan_mean.head(6))

# Beberapa fungsi agregasi sekaligus
bulanan_stats = df['penjualan'].resample('ME').agg(['mean', 'sum', 'min', 'max', 'std'])
print("\nStatistik bulanan:")
print(bulanan_stats.head(6))

Downsampling: Dari Harian ke Mingguan

# Resampling mingguan — total penjualan per minggu
mingguan_total = df['penjualan'].resample('W').sum()

# Resampling mingguan dimulai dari Senin
mingguan_senin = df['penjualan'].resample('W-MON').sum()

print("Total penjualan mingguan (5 pertama):")
print(mingguan_total.head())

Downsampling: Dari Harian ke Kuartalan

# Resampling kuartalan
kuartalan = df['penjualan'].resample('QE').agg(
    rata_rata='mean',
    total='sum',
    jumlah_hari='count'
)
print("Statistik kuartalan:")
print(kuartalan)

Upsampling: Dari Bulanan ke Harian

Upsampling agak tricky karena kita pada dasarnya "mengisi kekosongan". Pandas menyediakan beberapa cara untuk menangani NaN yang muncul setelah upsampling:

# Buat data bulanan terlebih dahulu
data_bulanan = df['penjualan'].resample('ME').mean()

# Upsampling ke harian — menghasilkan NaN
harian_dari_bulanan = data_bulanan.resample('D').asfreq()
print("Setelah upsampling (banyak NaN):")
print(harian_dari_bulanan.head(10))

# Mengisi NaN dengan forward fill
harian_ffill = data_bulanan.resample('D').ffill()

# Mengisi NaN dengan interpolasi linear
harian_interpolasi = data_bulanan.resample('D').interpolate(method='linear')

# Perbandingan metode pengisian
perbandingan = pd.DataFrame({
    'asfreq': harian_dari_bulanan,
    'ffill': harian_ffill,
    'interpolasi': harian_interpolasi
})
print("\nPerbandingan metode pengisian:")
print(perbandingan.dropna(subset=['asfreq']).head())

Resampling dengan Groupby untuk Multi-Kategori

Ini teknik yang sering saya pakai di proyek nyata — menggabungkan groupby() dan resample() untuk menganalisis beberapa kategori sekaligus:

# Resampling per kategori produk
bulanan_per_kategori = df.groupby('kategori')['penjualan'].resample('ME').mean()
print("Rata-rata bulanan per kategori:")
print(bulanan_per_kategori.head(9))

# Alternatif: gunakan unstack untuk format tabel yang lebih rapi
tabel_kategori = bulanan_per_kategori.unstack(level=0)
print("\nFormat tabel:")
print(tabel_kategori.head())

Rolling Window: Rata-rata Bergerak dan Statistik Berjalan

Rolling window (atau jendela bergerak) adalah teknik yang menghitung statistik pada "jendela" data berukuran tetap yang bergeser sepanjang time series. Yang penting dipahami: berbeda dengan resampling yang mengubah frekuensi data, rolling window mempertahankan frekuensi asli. Jumlah baris output-nya tetap sama.

Perbedaan Kunci: resample() vs rolling()

  • resample() — berbasis frekuensi waktu, jumlah baris output berubah
  • rolling() — berbasis ukuran jendela, jumlah baris tetap

Ini perbedaan yang kelihatannya kecil tapi dampaknya besar. Saya pernah lihat junior developer bingung kenapa output-nya "aneh" — ternyata karena pakai rolling padahal butuh resample, atau sebaliknya.

Simple Moving Average (SMA)

# Moving average 7 hari (1 minggu)
df['sma_7'] = df['penjualan'].rolling(window=7).mean()

# Moving average 30 hari (1 bulan)
df['sma_30'] = df['penjualan'].rolling(window=30).mean()

# Moving average 90 hari (1 kuartal)
df['sma_90'] = df['penjualan'].rolling(window=90).mean()

print("Data dengan moving averages:")
print(df[['penjualan', 'sma_7', 'sma_30', 'sma_90']].dropna().head(10))

Catatan penting: Secara default, perhitungan baru dimulai setelah jendela penuh terisi. Artinya baris pertama sampai ke-(window-1) akan bernilai NaN. Kalau ini mengganggu, pakai parameter min_periods — lebih lanjut di bawah.

Parameter min_periods dan center

# min_periods: hitung meskipun jendela belum penuh
df['sma_7_partial'] = df['penjualan'].rolling(window=7, min_periods=1).mean()

# center: tempatkan hasil di tengah jendela, bukan di ujung
df['sma_7_center'] = df['penjualan'].rolling(window=7, center=True).mean()

# Perbandingan
print(df[['penjualan', 'sma_7', 'sma_7_partial', 'sma_7_center']].head(10))

Rolling Standard Deviation untuk Deteksi Volatilitas

Ini salah satu use case favorit saya. Rolling std bisa membantu kamu mendeteksi periode-periode "bergejolak" dalam data:

# Rolling standard deviation 30 hari
df['rolling_std_30'] = df['penjualan'].rolling(window=30).std()

# Identifikasi periode volatilitas tinggi
rata_rata_std = df['rolling_std_30'].mean()
df['volatilitas_tinggi'] = df['rolling_std_30'] > (rata_rata_std * 1.5)

print(f"Rata-rata standar deviasi: {rata_rata_std:.2f}")
print(f"Jumlah hari volatilitas tinggi: {df['volatilitas_tinggi'].sum()}")

Multiple Aggregasi dengan Rolling

# Beberapa statistik rolling sekaligus
rolling_30 = df['penjualan'].rolling(window=30).agg(['mean', 'std', 'min', 'max'])
rolling_30.columns = ['mean_30d', 'std_30d', 'min_30d', 'max_30d']

print("Rolling statistics 30 hari:")
print(rolling_30.dropna().head())

Rolling Window Berbasis Waktu

Selain menggunakan jumlah baris tetap, kamu juga bisa definisikan jendela berdasarkan durasi waktu. Ini berguna banget kalau data kamu nggak berfrekuensi seragam (misalnya ada hari yang hilang karena libur):

# Rolling window 14 hari (berbasis waktu, bukan jumlah baris)
df['sma_14d'] = df['penjualan'].rolling(window='14D').mean()

# Rolling window 1 bulan
df['sma_1m'] = df['penjualan'].rolling(window='30D').mean()

print("Rolling berbasis waktu:")
print(df[['penjualan', 'sma_14d', 'sma_1m']].head(20))

Expanding Window dan EWMA

Expanding Window

Expanding window menghitung statistik kumulatif. Bedanya dengan rolling: jendela dimulai dari baris pertama dan terus bertambah, nggak pernah "lupa" data sebelumnya:

# Rata-rata kumulatif
df['cumulative_mean'] = df['penjualan'].expanding().mean()

# Maksimum kumulatif
df['cumulative_max'] = df['penjualan'].expanding().max()

# Standar deviasi kumulatif
df['cumulative_std'] = df['penjualan'].expanding().std()

print("Statistik kumulatif:")
print(df[['penjualan', 'cumulative_mean', 'cumulative_max']].tail())

Exponentially Weighted Moving Average (EWMA)

EWMA itu versi "lebih pintar" dari SMA biasa. Alih-alih memberi bobot yang sama ke semua data dalam jendela, EWMA memberi bobot lebih besar pada data terbaru. Hasilnya? Lebih responsif terhadap perubahan terkini.

# EWMA dengan span 7 hari
df['ewma_7'] = df['penjualan'].ewm(span=7).mean()

# EWMA dengan span 30 hari
df['ewma_30'] = df['penjualan'].ewm(span=30).mean()

# Perbandingan SMA vs EWMA
perbandingan_ma = df[['penjualan', 'sma_7', 'ewma_7']].dropna()
print("SMA vs EWMA (7 hari):")
print(perbandingan_ma.head(10))

Kalau kamu kerja di bidang keuangan atau monitoring real-time, EWMA biasanya jadi pilihan yang lebih baik dibanding SMA.

Shifting dan Differencing

Dua operasi ini mungkin kelihatan sederhana, tapi perannya sangat penting — terutama untuk bikin fitur lag di model prediktif dan mengecek stasioneritas data.

Shift: Menggeser Data

# Shift ke depan 1 hari (nilai kemarin)
df['penjualan_kemarin'] = df['penjualan'].shift(1)

# Shift ke depan 7 hari (nilai seminggu lalu)
df['penjualan_minggu_lalu'] = df['penjualan'].shift(7)

# Perubahan harian (hari ini - kemarin)
df['perubahan_harian'] = df['penjualan'] - df['penjualan'].shift(1)

# Persentase perubahan harian
df['pct_change'] = df['penjualan'].pct_change() * 100

print("Data dengan lag features:")
print(df[['penjualan', 'penjualan_kemarin', 'perubahan_harian', 'pct_change']].dropna().head())

Differencing untuk Stasioneritas

# Differencing orde pertama
df['diff_1'] = df['penjualan'].diff(1)

# Differencing orde kedua
df['diff_2'] = df['penjualan'].diff(2)

# Differencing musiman (lag 7 untuk siklus mingguan)
df['diff_musiman_7'] = df['penjualan'].diff(7)

# Differencing musiman (lag 365 untuk siklus tahunan)
df['diff_musiman_365'] = df['penjualan'].diff(365)

print("Differencing:")
print(df[['penjualan', 'diff_1', 'diff_musiman_7']].dropna().head())

Visualisasi Data Time Series

Analisis tanpa visualisasi itu ibarat masak tanpa nyicip — kamu nggak benar-benar tahu hasilnya. Berikut beberapa teknik visualisasi yang paling sering saya gunakan dalam proyek time series.

Plot Data Mentah dengan Moving Averages

fig, ax = plt.subplots(figsize=(14, 6))

ax.plot(df.index, df['penjualan'], alpha=0.3, label='Data Harian', color='gray')
ax.plot(df.index, df['sma_7'], label='SMA 7 Hari', linewidth=1.5, color='blue')
ax.plot(df.index, df['sma_30'], label='SMA 30 Hari', linewidth=2, color='red')
ax.plot(df.index, df['sma_90'], label='SMA 90 Hari', linewidth=2, color='green')

ax.set_title('Penjualan Harian dengan Moving Averages', fontsize=14)
ax.set_xlabel('Tanggal')
ax.set_ylabel('Penjualan')
ax.legend()
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=3))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

Heatmap Penjualan Bulanan

Heatmap ini salah satu cara paling efektif untuk melihat pola musiman dalam data. Satu pandangan, dan kamu langsung tahu bulan mana yang performanya tinggi:

# Buat pivot table untuk heatmap
df_pivot = df['penjualan'].groupby(
    [df.index.year, df.index.month]
).mean().unstack()
df_pivot.index.name = 'Tahun'
df_pivot.columns = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun',
                     'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des']

fig, ax = plt.subplots(figsize=(12, 4))
sns.heatmap(df_pivot, annot=True, fmt='.1f', cmap='YlOrRd',
            linewidths=0.5, ax=ax)
ax.set_title('Rata-rata Penjualan per Bulan', fontsize=14)
plt.tight_layout()
plt.show()

Plot Dekomposisi Musiman

from statsmodels.tsa.seasonal import seasonal_decompose

# Dekomposisi aditif dengan periode 30 hari
decompose = seasonal_decompose(
    df['penjualan'],
    model='additive',
    period=30
)

fig, axes = plt.subplots(4, 1, figsize=(14, 10), sharex=True)

decompose.observed.plot(ax=axes[0], title='Data Asli')
decompose.trend.plot(ax=axes[1], title='Tren')
decompose.seasonal.plot(ax=axes[2], title='Musiman')
decompose.resid.plot(ax=axes[3], title='Residual')

plt.tight_layout()
plt.show()

Bollinger Bands

Bollinger Bands menggabungkan rolling mean dengan rolling standard deviation. Awalnya populer di dunia trading, tapi sebenarnya bisa dipakai di mana saja kamu butuh visualisasi "batas normal" data:

window = 20
df['bb_mean'] = df['penjualan'].rolling(window=window).mean()
df['bb_upper'] = df['bb_mean'] + 2 * df['penjualan'].rolling(window=window).std()
df['bb_lower'] = df['bb_mean'] - 2 * df['penjualan'].rolling(window=window).std()

fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(df.index, df['penjualan'], alpha=0.3, color='gray', label='Data Harian')
ax.plot(df.index, df['bb_mean'], color='blue', label=f'SMA {window} Hari')
ax.fill_between(df.index, df['bb_lower'], df['bb_upper'],
                alpha=0.2, color='blue', label='Bollinger Bands (2σ)')
ax.set_title('Penjualan dengan Bollinger Bands', fontsize=14)
ax.legend()
plt.tight_layout()
plt.show()

Studi Kasus: Pipeline Analisis Time Series Lengkap

Sekarang mari kita satukan semua teknik di atas jadi satu pipeline yang rapi. Fungsi ini bisa langsung kamu pakai (atau modifikasi) di proyek kamu sendiri:

def analisis_time_series(df, kolom_nilai, freq_resample='ME'):
    """
    Pipeline analisis time series lengkap.
    
    Parameters:
        df: DataFrame dengan DatetimeIndex
        kolom_nilai: nama kolom yang akan dianalisis
        freq_resample: frekuensi resampling (default: bulanan)
    
    Returns:
        dict berisi hasil analisis
    """
    hasil = {}
    
    # 1. Statistik deskriptif
    hasil['deskriptif'] = df[kolom_nilai].describe()
    
    # 2. Resampling
    resampled = df[kolom_nilai].resample(freq_resample).agg(
        ['mean', 'sum', 'std', 'count']
    )
    hasil['resampled'] = resampled
    
    # 3. Moving averages
    hasil['sma_7'] = df[kolom_nilai].rolling(7).mean()
    hasil['sma_30'] = df[kolom_nilai].rolling(30).mean()
    hasil['ewma_7'] = df[kolom_nilai].ewm(span=7).mean()
    
    # 4. Volatilitas (rolling std)
    hasil['volatilitas'] = df[kolom_nilai].rolling(30).std()
    
    # 5. Perubahan periode
    hasil['pct_change'] = df[kolom_nilai].pct_change()
    
    # 6. Autokorelasi
    lags = [1, 7, 30, 365]
    hasil['autokorelasi'] = {
        f'lag_{lag}': df[kolom_nilai].autocorr(lag=lag) 
        for lag in lags if lag < len(df)
    }
    
    return hasil

# Jalankan pipeline
hasil_analisis = analisis_time_series(df, 'penjualan')

print("=== Statistik Deskriptif ===")
print(hasil_analisis['deskriptif'])
print("\n=== Autokorelasi ===")
for lag, val in hasil_analisis['autokorelasi'].items():
    print(f"  {lag}: {val:.4f}")
print("\n=== Resampling Bulanan (5 pertama) ===")
print(hasil_analisis['resampled'].head())

Tips Performa untuk Dataset Besar

Kalau kamu sudah bekerja dengan jutaan baris data time series (dan percayalah, ini lebih cepat terjadi dari yang kamu kira), berikut beberapa tips yang sudah teruji:

  • Konversi tipe data sedini mungkin: Pastikan kolom tanggal bertipe datetime64[ns] sejak awal. Operasi pada tipe datetime jauh lebih cepat dibanding string.
  • Manfaatkan Copy-on-Write: Pandas 3.0 mengaktifkan Copy-on-Write secara default. Ini berarti operasi indexing nggak lagi bikin salinan yang nggak perlu — hemat memori secara signifikan.
  • Coba engine='numexpr': Untuk operasi aritmetika pada DataFrame besar, eval() dengan engine numexpr bisa jauh lebih cepat.
  • Hindari loop Python: Selalu gunakan operasi vektorisasi pandas/numpy. Pakai .rolling().mean() daripada menghitung rata-rata bergerak dengan for loop manual. Perbedaan kecepatannya bisa ratusan kali lipat.
  • Chunk processing untuk file besar: Untuk CSV yang sangat besar, gunakan parameter chunksize di pd.read_csv().

Perubahan Penting di Pandas 3.0 untuk Time Series

Sebelum kamu mulai migrasi kode lama ke pandas 3.0, ada beberapa breaking changes yang perlu diperhatikan:

  • offsets.Day sekarang calendar-day: Dulu offsets.Day selalu 24 jam. Sekarang mengikuti kalender dan menghormati transisi DST. Ini bisa bikin hasil perhitungan berbeda kalau data kamu melintasi zona waktu.
  • Offset alias diperbarui: 'ME' gantikan 'M', 'YE' gantikan 'Y', 'QE' gantikan 'Q', 'h' gantikan 'H', 'min' gantikan 'T', 's' gantikan 'S'.
  • Parameter kind dihapus dari resample(): Kalau kode lama kamu pakai parameter ini, hapus saja.
  • Copy-on-Write aktif default: Chained assignment kayak df['col'][0] = val nggak lagi berfungsi. Gunakan .loc[] untuk assignment.
  • Tipe string baru: Kolom string otomatis pakai tipe str yang lebih efisien (didukung PyArrow kalau terinstal).

FAQ

Apa perbedaan antara resample() dan rolling() di pandas?

resample() mengubah frekuensi data time series (misalnya dari harian ke bulanan), sehingga jumlah baris output berubah. Sementara rolling() menghitung statistik pada jendela bergerak dengan ukuran tetap tanpa mengubah frekuensi — jumlah baris tetap sama. Pakai resample() untuk agregasi dan rolling() untuk smoothing atau deteksi anomali.

Bagaimana cara mengatasi error offset alias setelah upgrade ke pandas 3.0?

Ganti alias lama: 'M' jadi 'ME', 'Y' jadi 'YE', 'Q' jadi 'QE', 'H' jadi 'h', 'T' jadi 'min', dan 'S' jadi 's'. Tips dari pengalaman: upgrade ke pandas 2.3 dulu dan selesaikan semua FutureWarning sebelum loncat ke 3.0. Jauh lebih smooth.

Kapan sebaiknya menggunakan EWMA daripada SMA?

Pilih EWMA kalau data terbaru lebih penting dari data lama — misalnya untuk analisis keuangan, deteksi anomali real-time, atau monitoring. SMA lebih cocok buat melihat tren jangka panjang karena semua data dalam jendela dapat bobot yang sama.

Bagaimana cara mengisi nilai NaN setelah upsampling?

Ada tiga opsi utama: ffill() mengisi dengan nilai terakhir yang diketahui, bfill() mengisi dengan nilai berikutnya, dan interpolate() menghitung nilai berdasarkan interpolasi. Aturan praktisnya: pakai ffill() untuk data kategorikal atau diskrit, dan interpolate(method='linear') untuk data kontinu yang berubah gradual.

Mengapa data time series perlu dibuat stasioner sebelum pemodelan?

Banyak model statistik (ARIMA, misalnya) mengasumsikan data stasioner — mean, varians, dan autokorelasi konstan sepanjang waktu. Data non-stasioner bisa bikin prediksi jadi nggak valid. Cara menanganinya: gunakan diff() untuk differencing, atau log transformation untuk menstabilkan varians. Untuk menguji stasioneritas, pakai Augmented Dickey-Fuller test dari statsmodels.

Tentang Penulis Editorial Team

Our team of expert writers and editors.