Referensi cepat Python untuk data science. NumPy, Pandas, statistik, visualisasi, data cleaning, dan workflow analisis yang bisa langsung kamu pakai.
Login atau daftar akun gratis untuk membaca cheat sheet ini.
Data science lebih enak dikerjakan dalam virtual environment terpisah. Simpan dependency proyek di file yang jelas supaya notebook atau script kamu bisa diputar ulang di mesin lain.
python -m venv .venv
source .venv/bin/activate # Linux atau macOS
# .venv\Scripts\Activate.ps1 # PowerShell Windows
python -m pip install --upgrade pip
python -m pip install numpy pandas matplotlib jupyter
python -m pip freeze > requirements.txtJalankan notebook dari direktori proyek, bukan dari folder acak. Path relatif akan lebih mudah dipahami ketika kamu membaca ulang pekerjaan ini dua minggu lagi.
jupyter lab
# atau
jupyter notebookStruktur minimal yang cukup sehat:
proyek-analisis/
├── data/
│ ├── raw/
│ └── processed/
├── notebooks/
├── src/
├── requirements.txt
└── README.mddata/raw jangan ditimpa. Hasil pembersihan masuk ke data/processed, lalu kode transformasinya masuk ke src. Notebook cocok untuk eksplorasi dan penjelasan, sedangkan proses yang dipakai berulang sebaiknya pindah ke modul Python biasa.
list menjaga urutan dan bisa diubah. tuple juga berurutan, tetapi tidak bisa diubah. dict menyimpan pasangan key dan value. set menyimpan nilai unik tanpa jaminan urutan.
nilai = [78, 92, 84, 92]
profil = {"nama": "Rani", "kota": "Bandung", "aktif": True}
kategori =
Pakai .get() saat key mungkin tidak ada. Akses data["key"] langsung akan memunculkan KeyError bila key tersebut tidak tersedia.
umur = profil.get("umur")
negara = profil.get("negara", "Indonesia")List comprehension pas untuk transformasi kecil yang tetap mudah dibaca. Kalau datanya besar atau hanya akan dibaca sekali, generator expression lebih hemat memori karena nilainya dihasilkan saat diminta.
angka = [1, 2, 3, 4, 5, 6]
kuadrat_genap = [x ** 2 for x in angka if x % 2 == 0]
Jangan memadatkan logika bisnis yang panjang ke satu comprehension. Loop biasa lebih gampang diuji dan di-debug.
Type hint tidak memaksa tipe saat runtime, tetapi editor dan type checker bisa menangkap banyak kesalahan sebelum program dijalankan. Pakai raise untuk data yang tidak masuk akal, bukan membiarkan hasil salah ikut mengalir ke tahap berikutnya.
from collections.abc import Sequence
def rata_rata(data: Sequence[float]) -> float:
if not data:
raise ValueError("data tidak boleh kosong")
return sum(data) / len(data)
Jangan menulis except Exception: pass. Itu menyembunyikan sumber masalah. Tangkap error yang kamu harapkan dan biarkan error lain terlihat saat pengembangan.
Modul standar csv dan json cukup untuk banyak kasus kecil. Gunakan encoding="utf-8" saat bekerja dengan teks Indonesia agar karakter seperti é atau nama lokasi tidak rusak.
import csv
import json
from pathlib import Path
path_csv = Path("data/raw/penjualan.csv")
with path_csv.open("r", encoding="utf-8", newline="")
csv.DictReader mengembalikan string. Ubah kolom numerik secara eksplisit. Jangan berharap Python menebak bahwa "125000" adalah integer.
for baris in baris:
baris["harga"] = int(baris["harga"])
baris["kuantitas"] = int(baris["kuantitas"])NumPy memakai ndarray, array N dimensi dengan tipe elemen yang umumnya sama. Untuk hitungan numerik berukuran besar, pendekatan ini lebih pas daripada loop Python per elemen. Konvensi import yang dipakai luas adalah import numpy as np.
import numpy as np
suhu = np.array([29.5, 30.1, 31.2, 30.8], dtype=np.float64)
matriks = np.array([[1, 2, 3], [4
np.empty() tidak mengisi dengan nol. Isinya berasal dari memori yang belum diinisialisasi, jadi isi array itu harus kamu tulis sebelum dibaca.
nol = np.zeros((2, 3), dtype=np.float64)
satu = np.ones(4, dtype=np.int64)
rentang = np.arange(0, 10, 2)
titik =
Pilih np.arange() ketika kamu tahu langkahnya. Pilih np.linspace() ketika kamu perlu jumlah titik tertentu, misalnya 100 titik untuk garis plot antara dua batas.
Index NumPy dimulai dari nol. Slicing array lazimnya menghasilkan view yang berbagi data dengan array asal. Ini beda dari slice pada list Python, yang membuat list baru.
nilai = np.array([70, 75, 80, 85, 90])
bagian = nilai[1:4]
bagian[0] = 999
print(nilai) # [ 70 999 80 85 90]
Pakai .copy() ketika hasil slice akan kamu ubah secara mandiri. Bug view sering bikin data sumber ikut berubah tanpa sengaja.
Operasi NumPy berjalan per elemen. Hindari loop Python untuk aritmetika sederhana pada seluruh array.
harga = np.array([12000, 25000, 18000], dtype=float)
kuantitas = np.array([2, 1, 3])
subtotal = harga * kuantitas
pajak =
Broadcasting membandingkan shape dari kanan ke kiri. Dimensi bernilai 1 dapat diperluas. Contoh berikut menambahkan rata rata setiap kolom ke data yang sudah dikurangi rata ratanya.
X = np.array([[10.0, 100.0], [20.0, 200.0], [30.0, 300.0]])
rata = X.mean(axis=0)
X_tengah = X - rata
print(rata)
axis=0 berarti agregasi sepanjang baris dan menyisakan satu nilai per kolom. axis=1 berarti agregasi sepanjang kolom dan menyisakan satu nilai per baris. Ini sumber salah hitung yang cukup sering. Cek shape sebelum lanjut.
Boolean mask memberi cara aman untuk menyaring nilai tanpa loop eksplisit.
nilai = np.array([55, 72, 88, np.nan, 91])
valid = ~np.isnan(nilai)
lulus = nilai[valid & (nilai >= 70)]
print(lulus) # [72. 88. 91.]Untuk membandingkan array floating point, pakai np.isclose() atau np.allclose(). Perhitungan biner tidak selalu membuat 0.1 + 0.2 == 0.3 tepat bernilai True.
hasil = 0.1 + 0.2
print(np.isclose(hasil, 0.3)) # TrueGunakan np.random.default_rng(seed) alih alih mengandalkan generator global. Seed membuat eksperimen kamu dapat diulang dengan angka acak yang sama.
rng = np.random.default_rng(42)
sampel = rng.normal(loc=0.0, scale=1.0, size=5)
indeks = rng.choice(10, size=3, replace
normal() menghasilkan sampel dari distribusi normal. choice(..., replace=False) memilih tanpa pengulangan dan akan gagal bila ukuran sampel lebih besar dari populasi.
Pandas memakai Series untuk satu kolom berlabel dan DataFrame untuk tabel. Mulai dengan inspeksi, lalu ubah data sedikit demi sedikit. Membaca seluruh kolom dan langsung membuat model biasanya berakhir dengan kejutan di tengah proses.
import pandas as pd
penjualan = pd.read_csv(
"data/raw/penjualan.csv",
parse_dates=["tanggal"],
dtype={"produk": "string", "kota": "string"},
)
.loc memilih berdasarkan label dan kondisi boolean. .iloc memilih berdasarkan posisi integer. Saat mengubah subset, pakai .loc supaya maksud kode jelas dan kamu tidak terkena SettingWithCopyWarning.
kolom = penjualan[["tanggal", "produk", "harga", "kuantitas"]].copy()
mask = (kolom["harga"] > 0) & (kolom["kuantitas"] > 0)
kolom
Hindari inplace=True sebagai kebiasaan. Assignment eksplisit lebih mudah dibaca dan tidak bergantung pada perilaku method tertentu.
Anggap missing value sebagai keputusan bisnis, bukan sekadar hal yang harus dihapus. Kolom harga hilang mungkin perlu dibuang. Kolom kota hilang mungkin perlu diberi label "Tidak diketahui" agar total transaksi tetap utuh.
bersih = penjualan.copy()
bersih = bersih.drop_duplicates()
bersih = bersih.dropna(subset=["harga", "kuantitas"])
bersih.loc[:, "kota"] = bersih["kota"].fillna("Tidak diketahui")
bersih.loc[:,
errors="coerce" mengubah nilai yang gagal diparse menjadi missing value. Hitung jumlahnya sebelum membuang baris agar kamu tahu apakah file sumber punya format yang kacau.
ringkasan_kota = (
bersih.assign(total=bersih["harga"] * bersih["kuantitas"])
.groupby("kota", as_index=False)
.agg(
transaksi=(
Sebelum merge, cek key unik di kedua tabel. Merge many to many yang tidak disengaja dapat melipatgandakan jumlah baris dan membuat omzet tampak naik tanpa alasan.
produk = pd.read_csv("data/raw/produk.csv")
assert produk["produk_id"].is_unique
lengkap = bersih.merge(
produk[["produk_id", "kategori"]],
on="produk_id",
how="left",
validate
Parameter validate="many_to_one" membuat Pandas menghentikan proses bila tabel kanan ternyata punya key ganda.
lengkap.loc[:, "bulan"] = lengkap["tanggal"].dt.to_period("M")
bulanan = lengkap.groupby("bulan", as_index=False)["total"].sum()
bulanan.to_csv("data/processed/omzet_bulanan.csv", index=False)
Parquet menyimpan tipe data dan biasanya lebih efisien untuk tabel analitik. Kamu perlu engine seperti pyarrow atau fastparquet untuk menulis file Parquet.
Mean mudah tertarik outlier. Median lebih tahan terhadap satu transaksi yang nilainya jauh di atas nilai umum. Python menyediakan modul statistics, tetapi untuk array dan tabel gunakan fungsi NumPy atau Pandas agar data tidak perlu bolak balik bentuk.
import numpy as np
x = np.array([100_000, 120_000, 115_000, 130_000, 5_000_000])
print(np.mean(x))
print(np.median(x))
print(np.quantile(x, [0.25, 0.5, 0.75
ddof=1 memberi standar deviasi sampel. Untuk seluruh populasi yang benar benar lengkap, gunakan ddof=0, nilai default NumPy. Jangan mencampur keduanya dalam satu laporan.
Korelasi tidak membuktikan sebab akibat. Cek juga ukuran sampel, outlier, dan apakah dua kolom punya hubungan logis sebelum menulis narasi dari angka tersebut.
numerik = lengkap.select_dtypes(include="number")
korelasi = numerik.corr(numeric_only=True)
print(korelasi.round(2))Plot yang baik menjawab satu pertanyaan. Tambahkan judul, label sumbu, dan satuan. Jangan gunakan grafik pai untuk puluhan kategori karena pembaca akan sulit membandingkan irisan kecil.
import matplotlib.pyplot as plt
urut = ringkasan_kota.sort_values("omzet")
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(urut["kota"], urut["omzet"], color=
Untuk melihat hubungan dua variabel dan outlier, pakai scatter plot.
fig, ax = plt.subplots()
ax.scatter(lengkap["kuantitas"], lengkap["total"], alpha=0.5)
ax.set_xlabel("Kuantitas")
ax.set_ylabel("Total transaksi")
ax.set_title("Kuantitas dan total transaksi")
plt.show()Kolom teks yang berisi kategori tidak bisa langsung masuk ke sebagian besar model numerik. Dua cara yang paling sering dipakai adalah pemetaan ordinal dan one hot encoding.
level = pd.Categorical(
bersih["level"],
categories=["pemula", "menengah", "lanjutan"],
ordered=True,
)
kode_level = level.codes
one_hot = pd.get_dummies(
pd.Categorical berguna saat kategori punya urutan, misalnya level pelanggan. pd.get_dummies berguna untuk kategori tanpa urutan, misalnya nama kota. Jangan mengkode level pemula jadi 1, menengah jadi 2, dan lanjutan jadi 3 hanya karena terlihat rapi. Kalau urutannya memang ada arti, kodekan secara eksplisit. Kalau tidak, biarkan one hot menangani kategori itu.
Kategori yang jarang muncul membuat jumlah kolom one hot membengkak. Kumpulkan nilai yang muncul sedikit ke dalam label "Lainnya" sebelum encoding.
hitungan = bersih["kota"].value_counts()
sering = hitungan[hitungan >= 5].index
bersih.loc[:, "kota_ringkas"] = bersih["kota"].where(
bersih["kota"].isin(sering),
"Lainnya",
)where mengganti nilai yang tidak memenuhi syarat dengan nilai pengganti. Baca dokumentasinya dengan teliti karena urutan argumennya bisa membingungkan saat pertama kali dipakai.
assert lengkap["harga"].ge(0).all()
assert lengkap["kuantitas"].ge(0).all()
assert lengkap["tanggal"].notna().all()Data science yang bisa dipercaya biasanya lahir dari pemeriksaan kecil seperti ini, bukan dari notebook penuh sel yang tidak pernah dijalankan ulang.
float64, int64, atau string.True dan False yang dipakai untuk memilih elemen atau baris.(3, 2) untuk tiga baris dan dua kolom.