Pada chapter sebelumnya, shift() menyediakan bahan mentah: nilai sebelumnya berdampingan dengan nilai sekarang, lalu kita menguranginya sendiri dengan pengurangan biasa. pandas menyediakan pintasannya dalam bentuk diff(), sebuah method yang menghitung selisih antarbaris sekaligus dalam satu panggilan. Selisih antarperiode adalah fondasi analisis deret waktu: tanpanya kita sulit melihat apakah penjualan naik atau turun, sebesar apa, dan dalam persen berapa. Chapter ini membahas diff() pada data numerik, selisih dengan jarak n periode, perubahan persentase lewat pct_change(), serta diff() pada kolom datetime.

Selisih Antarperiode #

df["penjualan"].diff() menghitung x_t - x_{t-1} untuk setiap baris, yang secara matematis identik dengan df["penjualan"] - df["penjualan"].shift(1). Baris pertama selalu NaN karena tidak ada nilai sebelumnya untuk dibandingkan, dan dtype hasilnya float64 demi menampung nilai kosong itu. Berbeda dengan shift() yang mengembalikan data mentah hasil geser, diff() langsung mengembalikan selisih siap analisis.

python
import pandas as pd

tanggal = pd.date_range("2026-01-01", "2026-01-08", freq="D")
df = pd.DataFrame(
    {"penjualan": [200, 202, 284, 286, 208, 210, 212, 214]},
    index=tanggal,
)
df.index.name = "tanggal"

df["selisih"] = df["penjualan"].diff()
print("diff() menghitung selisih dengan hari sebelumnya:")
print(df)

print("\ndiff(2) membandingkan dengan dua hari sebelumnya:")
print(df["penjualan"].diff(2))

print("\npct_change() dalam persen:")
persen = df["penjualan"].pct_change().mul(100).round(1)
print(persen)

kunjungan = pd.DataFrame(
    {
        "pelanggan": ["Budi", "Siti", "Dewi"],
        "kunjungan": pd.to_datetime(["2026-01-02", "2026-01-09", "2026-01-23"]),
    }
)
kunjungan["jarak_hari"] = kunjungan["kunjungan"].diff().dt.days
print("\ndiff() pada kolom datetime menghasilkan selisih waktu:")
print(kunjungan)

Output yang Dihasilkan:

text
diff() menghitung selisih dengan hari sebelumnya:
            penjualan  selisih
tanggal                       
2026-01-01        200      NaN
2026-01-02        202      2.0
2026-01-03        284     82.0
2026-01-04        286      2.0
2026-01-05        208    -78.0
2026-01-06        210      2.0
2026-01-07        212      2.0
2026-01-08        214      2.0

diff(2) membandingkan dengan dua hari sebelumnya:
tanggal
2026-01-01     NaN
2026-01-02     NaN
2026-01-03    84.0
2026-01-04    84.0
2026-01-05   -76.0
2026-01-06   -76.0
2026-01-07     4.0
2026-01-08     4.0
Freq: D, Name: penjualan, dtype: float64

pct_change() dalam persen:
tanggal
2026-01-01     NaN
2026-01-02     1.0
2026-01-03    40.6
2026-01-04     0.7
2026-01-05   -27.3
2026-01-06     1.0
2026-01-07     1.0
2026-01-08     0.9
Freq: D, Name: penjualan, dtype: float64

diff() pada kolom datetime menghasilkan selisih waktu:
  pelanggan  kunjungan  jarak_hari
0      Budi 2026-01-02         NaN
1      Siti 2026-01-09         7.0
2      Dewi 2026-01-23        14.0

Mari kita telaah baris-baris kuncinya:

  1. Baris 4-8: DataFrame delapan hari penjualan Januari 2026 dibuat dengan DatetimeIndex harian, dan df.index.name = "tanggal" memberi label pada index.
  2. Baris 10 (diff()): kolom selisih menangkap perubahan harian; lonjakan akhir pekan terbaca sebagai 82.0 pada 2026-01-03 dan koreksinya sebagai -78.0 pada 2026-01-05.
  3. Baris 15 (diff(2)): selisih dihitung terhadap dua hari sebelumnya, sehingga dua baris pertama bernilai NaN.
  4. Baris 18 (pct_change): perubahan relatif dihitung sebagai fraksi, lalu mul(100).round(1) mengubahnya menjadi persen dengan satu desimal.
  5. Baris 21-27 (diff pada datetime): kolom kunjungan bertipe datetime ikut di-diff; hasil selisih waktunya diambil dalam satuan hari lewat .dt.days.

Jarak Lebih dari Satu Periode #

Argumen pertama diff() adalah jumlah periode pembandingnya: diff() tanpa argumen sama dengan diff(1). Pada output, diff(2) menghasilkan 84.0 untuk 2026-01-03 karena nilai dibandingkan dengan 2026-01-01 (284 - 200). Nilai 84.0 berulang di 2026-01-04 dan pola serupa berlanjut, karena dataset tren linear kita memiliki kenaikan tetap dua unit per hari kerja. Pada data harian nyata, diff(7) adalah pilihan populer untuk membandingkan minggu ke minggu, sedangkan diff(12) cocok untuk data bulanan yang dipengaruhi musim; prinsipnya satu: jarak pembanding dinyatakan dalam jumlah baris, bukan satuan kalender.

Perubahan Persentase dengan pct_change() #

Selisih absolut seperti 82.0 belum menceritakan skala relatifnya: lonjakan 82 unit berbeda makanya pada penjualan 300 dan pada penjualan 3000. pct_change() menghitung (x_t - x_{t-1}) / x_{t-1}, yaitu selisih dibagi nilai pembanding, dan hasilnya berupa fraksi (0.125 berarti naik 12,5 persen). Karena itu pct_change().mul(100).round(1) menjadi pola lazim agar output terbaca sebagai persen, seperti 40.6 pada 2026-01-03. Perhatikan juga tanda negatif -27.3 pada 2026-01-05, yang menandakan penurunan sekaligus menunjukkan arah pergerakan dalam satu angka.

diff() pada Kolom Datetime #

Method ini tidak terbatas pada angka. Saat diterapkan pada kolom datetime, diff() menghasilkan selisih waktu bertipe timedelta64, dan .dt.days mengubahnya menjadi jumlah hari. Pada output, jarak kunjungan Budi ke Siti adalah 7.0 hari dan Siti ke Dewi 14.0 hari. Pola ini berguna untuk analisis retensi: berapa lama jeda antarpembelian tiap pelanggan, atau berapa hari jeda antar-transaksi yang menandakan perilaku berubah.

Dokumentasi pandas.DataFrame.diff merinci parameter periods dan axis, dan referensi pandas.Series.pct_change menjelaskan perilaku NaN yang berubah di era pandas modern; daftar perubahannya terangkum di whatsnew v3.0.0 . Sampai di sini, semua selisih yang kita hitung berbasis Timestamp, titik waktu yang presisi. Chapter berikutnya membahas tipe hasil selisih itu secara penuh: Timedelta untuk durasi, mulai dari to_timedelta() sampai pembacaan komponennya lewat accessor .dt.