10 minutes to pandas
pandas secukupnya: baca CSV, filter, groupby. Cukup untuk menganalisis log dan menyiapkan dataset eval.
Intisari
- DataFrame = tabel dengan kolom bernama. Bayangkan spreadsheet yang bisa diprogram.
- Untuk AI engineer, pandas dipakai untuk analisis log dan dataset eval โ bukan inti aplikasi.
- Lima operasi sudah menutup 90% kebutuhan:
read_csv, filter boolean,groupby,sort_values,to_csv. - Filter pakai mask boolean:
df[df.skor > 0.8]. - Jangan habiskan seminggu di sini. Kembali saat benar-benar ada data yang perlu dianalisis.
Di mana pandas terpakai di roadmap ini
| Kegunaan | Contoh |
|---|---|
| Analisis log LLM | Biaya per rute, distribusi latensi, tingkat error |
| Dataset eval | Muat pertanyaan + jawaban acuan, simpan hasil skor |
| Menyiapkan data ingest | Baca CSV metadata sebelum masuk vector store |
| Laporan cepat | Agregasi untuk dilihat sendiri, bukan untuk production |
pandas bukan bagian dari jalur request aplikasimu. Ia adalah alat analisis. Untuk memvalidasi data yang masuk aplikasi, pakai Pydantic. Untuk vektor, pakai NumPy. pandas dipakai saat kamu duduk melihat data dan bertanya "apa yang terjadi kemarin?"
uv add pandas
Membuat dan membaca
import pandas as pd
df = pd.DataFrame({
"pertanyaan": ["apa itu RAG?", "bagaimana cara deploy?"],
"skor": [0.92, 0.71],
"model": ["opus", "sonnet"],
})
df = pd.read_csv("log.csv")
df = pd.read_json("hasil.jsonl", lines=True)
df = pd.DataFrame(daftar_dict) # dari list of dict โ sering dipakai
Melihat isinya
df.head() # 5 baris pertama
df.tail(10)
df.shape # (jumlah_baris, jumlah_kolom)
df.columns
df.dtypes
df.info() # ringkasan: tipe, jumlah non-null, memori
df.describe() # statistik untuk kolom numerik
Memilih
df["skor"] # satu kolom โ Series
df[["pertanyaan", "skor"]] # beberapa kolom โ DataFrame
df.iloc[0] # baris ke-0 berdasarkan posisi
df.iloc[0:5]
df.loc[df.skor > 0.8, "pertanyaan"] # baris yang lolos filter, kolom tertentu
Filter
df[df.skor > 0.8]
df[(df.skor > 0.8) & (df.model == "opus")] # & dan |, dengan tanda kurung
df[df.model.isin(["opus", "sonnet"])]
df[df.pertanyaan.str.contains("RAG", case=False)]
df[df.skor.isna()] # baris yang kosong
Pakai & dan |, bukan and dan or
โ dan bungkus tiap kondisi dengan tanda kurung. and bekerja pada satu nilai boolean,
sedangkan filter pandas bekerja pada seluruh kolom sekaligus.
Kolom baru
df["biaya"] = (df.token_masuk * 5 + df.token_keluar * 25) / 1_000_000
df["lulus"] = df.skor >= 0.7
df["panjang"] = df.pertanyaan.str.len()
df["kategori"] = df.skor.apply(lambda s: "baik" if s > 0.8 else "kurang")
groupby
df.groupby("model").skor.mean()
df.groupby("model").agg(
jumlah=("skor", "count"),
skor_rata=("skor", "mean"),
biaya_total=("biaya", "sum"),
latensi_p95=("latensi_ms", lambda s: s.quantile(0.95)),
)
# Contoh nyata: biaya per rute per hari
df["tanggal"] = pd.to_datetime(df.waktu).dt.date
(df.groupby(["tanggal", "rute"])
.agg(panggilan=("id", "count"), biaya=("biaya", "sum"))
.sort_values("biaya", ascending=False))
Analisis seperti ini yang mengubah keputusan. Kamu mungkin menemukan bahwa satu rute klasifikasi menghabiskan 60% biaya karena memakai model termahal โ padahal Haiku sudah cukup. Tanpa data, itu tebakan; dengan data, itu keputusan.
Mengurutkan dan menghitung
df.sort_values("skor", ascending=False)
df.sort_values(["model", "skor"], ascending=[True, False])
df.model.value_counts() # frekuensi tiap nilai
df.skor.quantile([0.5, 0.95, 0.99])
df.nlargest(10, "biaya")
Menangani data kosong
df.isna().sum() # berapa kosong per kolom
df.dropna() # buang baris yang punya kosong
df.dropna(subset=["skor"])
df.fillna(0)
df.skor.fillna(df.skor.mean())
Menyimpan
df.to_csv("hasil.csv", index=False) # index=False supaya tidak ada kolom nomor
df.to_json("hasil.jsonl", orient="records", lines=True)
df.to_parquet("hasil.parquet") # jauh lebih kecil dan cepat untuk data besar
Contoh: menganalisis hasil eval RAG
import pandas as pd
df = pd.read_json("hasil_eval.jsonl", lines=True)
print(f"total pertanyaan : {len(df)}")
print(f"tingkat lulus : {(df.skor >= 0.7).mean():.1%}")
print(f"skor rata-rata : {df.skor.mean():.3f}")
print(f"latensi p95 : {df.latensi_ms.quantile(0.95):.0f} ms")
print(f"total biaya : ${df.biaya.sum():.4f}")
print("\nSkor terburuk:")
print(df.nsmallest(5, "skor")[["pertanyaan", "skor", "jawaban"]])
print("\nPer kategori:")
print(df.groupby("kategori").agg(
n=("skor", "count"),
rata=("skor", "mean"),
lulus=("skor", lambda s: (s >= 0.7).mean()),
))
Yang bisa dilewati
- MultiIndex dan indexing hierarkis
pivot_table,melt,stack/unstack- Time series lanjutan (resampling, rolling window)
- Optimasi kategorikal dan memori
- Merge dan join yang kompleks
Semuanya berguna โ tapi bukan sekarang. Kembali ke sini saat ada masalah nyata yang membutuhkannya.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.