pandasdatetimeMenengah5 mnt baca

Datetime di Pandas: to_datetime & .dt

Ubah teks jadi tanggal betulan, pecah jadi tahun/bulan/hari, dan agregasi per periode dengan resample.

Dari Teks Mati jadi Tanggal Hidup

Kolom tanggal yang tipenya teks itu seperti kalender yang digambar di kertas: kelihatan, tapi tidak bisa dipakai menghitung. Setelah dikonversi jadi datetime, kolom itu jadi "hidup": bisa diurutkan kronologis, diselisihi, dipecah jadi tahun/bulan/hari, dan diagregasi per minggu atau bulan.

Kenapa penting untuk data analyst? Karena hampir semua pertanyaan bisnis berbau waktu: tren penjualan bulanan, perbandingan kuartal ini vs kuartal lalu, hari apa yang paling ramai. Semua itu mustahil (atau menyiksa) kalau kolom tanggal masih berupa string.

to_datetime(): Menghidupkan Kolom Tanggal

python
import pandas as pd

df = pd.DataFrame({
    "tanggal": ["2024-01-05", "2024-01-12", "2024-02-03", "2024-02-20"],
    "omzet": [500, 700, 600, 900],
})

df["tanggal"] = pd.to_datetime(df["tanggal"])
print(df["tanggal"].dtype)  # datetime64[ns]

Untuk format tanggal Indonesia (tanggal/bulan/tahun), tambahkan dayfirst=True atau format eksplisit:

python
df2 = pd.DataFrame({"tgl": ["05/01/2024", "12/01/2024", "03/02/2024"]})

# Cara 1: dayfirst
df2["tgl"] = pd.to_datetime(df2["tgl"], dayfirst=True)

# Cara 2: format eksplisit (lebih cepat dan tidak ambigu)
df2["tgl"] = pd.to_datetime(df2["tgl"], format="%d/%m/%Y")
print(df2["tgl"].tolist())

Accessor .dt: Memecah Tanggal

Setelah jadi datetime, accessor .dt membuka semua komponennya.

python
df["tahun"] = df["tanggal"].dt.year
df["bulan"] = df["tanggal"].dt.month
df["nama_bulan"] = df["tanggal"].dt.month_name()
df["hari"] = df["tanggal"].dt.day
df["nama_hari"] = df["tanggal"].dt.day_name()
df["kuartal"] = df["tanggal"].dt.quarter

print(df[["tanggal", "nama_hari", "kuartal"]])

Contoh realistis, mencari hari tersibuk dalam seminggu:

python
df = pd.DataFrame({
    "tanggal": pd.to_datetime(["2024-01-01", "2024-01-02", "2024-01-08",
                               "2024-01-09", "2024-01-09", "2024-01-15"]),
    "pengunjung": [120, 150, 130, 170, 160, 140],
})

df["hari"] = df["tanggal"].dt.day_name()
tersibuk = df.groupby("hari")["pengunjung"].sum().sort_values(ascending=False)
print(tersibuk)

resample(): Agregasi per Periode Waktu

resample() adalah groupby khusus waktu. Syaratnya: kolom tanggal jadi index dulu (atau pakai parameter on).

python
df = pd.DataFrame({
    "tanggal": pd.to_datetime(["2024-01-05", "2024-01-12", "2024-01-20",
                               "2024-02-03", "2024-02-15", "2024-03-01"]),
    "omzet": [500, 700, 600, 900, 800, 1000],
})
df = df.set_index("tanggal")

# Omzet per bulan (ME = month-end)
per_bulan = df.resample("ME").sum()
print(per_bulan)
#             omzet
# tanggal
# 2024-01-31   1800
# 2024-02-29   1700
# 2024-03-31   1000

# Rata-rata per minggu
per_minggu = df.resample("W").mean()
print(per_minggu)

Kode frekuensi yang paling sering dipakai: "D" harian, "W" mingguan, "ME" bulanan, "QE" kuartalan, "YE" tahunan.

Catatan teknis: resample mengisi periode yang kosong dengan NaN (bukan menghilangkannya). Ini justru berguna: kamu bisa melihat bulan mana yang tidak ada transaksi sama sekali, lalu memutuskan dengan fillna(0) atau membiarkannya.

Jebakan Umum

SALAH, mengurutkan tanggal yang masih string:

python
# Jangan: urutan alfabet, bukan kronologis!
s = pd.Series(["05/01/2024", "12/01/2024", "03/02/2024"])
print(s.sort_values().tolist())
# ['03/02/2024', '05/01/2024', '12/01/2024'] <- salah urutan!

BENAR, konversi dulu baru urutkan:

python
# Lakukan: datetime diurutkan dengan benar
s = pd.Series(["05/01/2024", "12/01/2024", "03/02/2024"])
s = pd.to_datetime(s, format="%d/%m/%Y")
print(s.sort_values().dt.strftime("%d/%m/%Y").tolist())
# ['05/01/2024', '12/01/2024', '03/02/2024'] <- kronologis benar

SALAH, resample tanpa datetime index:

python
# Jangan: kolom tanggal masih kolom biasa
df = pd.DataFrame({"tanggal": ["2024-01-05"], "omzet": [500]})
df.resample("ME", on="tanggal").sum()  # TypeError: tanggal bukan datetime

BENAR, konversi dulu atau set sebagai index:

python
# Lakukan: pastikan datetime sebelum resample
df = pd.DataFrame({"tanggal": ["2024-01-05", "2024-02-10"], "omzet": [500, 700]})
df["tanggal"] = pd.to_datetime(df["tanggal"])
print(df.resample("ME", on="tanggal").sum())

Tantangan

Tren omzet bulanan dari data harian

Diberi DataFrame dengan kolom tanggal ["2024-01-05", "2024-01-20", "2024-02-03", "2024-02-18", "2024-03-10"] dan omzet [500, 700, 600, 900, 1000]. Konversi tanggal jadi datetime, jadikan index, lalu resample per bulan ("ME") untuk total omzet. Cetak hasilnya.

Kuis Bab

Uji pemahamanmu: Bab 6: Data Cleaning dan Transformasi

Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".

1.Apa yang dikembalikan df.isna().sum()?

2.Kapan sebaiknya memakai drop_duplicates()?

3.Dalam metode IQR, nilai dianggap outlier jika...

4.Apa beda pd.merge(df_a, df_b, how='left') dengan how='inner'?

5.Kenapa kolom tanggal string perlu diubah dengan pd.to_datetime()?