Python untuk Data Science
Kuasai dasar Python dan library inti — NumPy dan Pandas — yang menjadi tulang punggung setiap proyek data science.
Peta Ekosistem — Dimanakah Kita Berada?
┌─────────────────────────────────────────────────────────┐ │ APLIKASI & VISUALISASI │ │ Streamlit · Dash · Matplotlib · Seaborn · Plotly │ ├─────────────────────────────────────────────────────────┤ │ MACHINE LEARNING │ │ Scikit-learn · XGBoost · TensorFlow · PyTorch │ ├──────────────────┬──────────────────────────────────────┤ │ PANDAS ◄ BAB INI │ STATISTIKA │ │ Manipulasi │ SciPy · statsmodels │ │ tabular │ │ ├──────────────────┤ │ │ NUMPY ◄ BAB INI │ │ │ Komputasi │ │ │ numerik │ │ ├──────────────────┴──────────────────────────────────────┤ │ PYTHON DASAR ◄ BAB INI │ │ Variabel · Fungsi · Struktur Data · OOP │ └─────────────────────────────────────────────────────────┘
Bab ini membangun fondasi dari lapisan paling bawah hingga Pandas. Layer di atasnya akan kita pelajari di bab-bab selanjutnya.
2.1 Review Python Dasar
Refresh singkat fitur Python yang paling sering digunakan dalam pipeline data science.
Variabel & Tipe Data
String & f-String
f-string (Python 3.6+) adalah cara paling readable untuk memformat output — sangat berguna saat membuat laporan.
Struktur Data Inti
Ilustrasi: Struktur Data Python
LIST (terurut, bisa diubah) DICT (key → value) ┌───┬───┬───┬───┐ ┌──────────┬────────┐ │ 85│ 92│ 78│ 95│ │ "nama" │ "Budi" │ └───┴───┴───┴───┘ │ "usia" │ 25 │ 0 1 2 3 ← index │ "nilai" │[85,92] │ └──────────┴────────┘ SET (unik, tidak terurut) TUPLE (terurut, immutable) ┌───┐ ┌──────┬──────┐ │HR │ │-6.2 │106.8 │ ├───┤ └──────┴──────┘ │Tek│ lat lon ├───┤ │Mkt│ └───┘
Fungsi
Error Handling
Dalam pipeline data, file bisa hilang, format bisa salah, atau tipe data tidak sesuai. Gunakan try/except agar program tidak crash di tengah jalan.
import numpy as np dan import pandas as pd — alias ini bersifat universal di seluruh ekosistem data science. Jangan gunakan alias lain.2.2 NumPy: Komputasi Numerik
NumPy menyediakan ndarray — array multidimensi berkinerja tinggi yang menjadi fondasi Pandas, Scikit-learn, dan hampir semua library ML.
Mengapa NumPy Lebih Cepat dari List?
Python List — setiap elemen adalah objek terpisah list_obj ──► [ptr]──► int_obj(1) ← lokasi memori acak [ptr]──► int_obj(2) tiap akses butuh lookup [ptr]──► int_obj(3) overhead ~28 byte/angka [ptr]──► int_obj(4) NumPy ndarray — blok memori kontigu bertipe tetap ndarray ──► [ 1 | 2 | 3 | 4 ] ← blok C-contiguous ↑ tipe tetap (int64 = 8 byte) satu pointer vektorisasi via C/Fortran ke blok ~100x lebih cepat untuk operasi numerik
Membuat Array
Ilustrasi: Bentuk-Bentuk Array
1D — shape (5,) 2D — shape (3, 4) 3D — shape (2, 3, 2) ┌───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┐ │ 1 │ 2 │ 3 │ 4 │ 5 │ │ 0 │ 0 │ 0 │ 0 │ │ 0 │ 1 │ ← slice 0 └───┴───┴───┴───┴───┘ ├───┼───┼───┼───┤ │ 2 │ 3 │ │ 0 │ 0 │ 0 │ 0 │ │ 4 │ 5 │ ├───┼───┼───┼───┤ └───┴───┘ │ 0 │ 0 │ 0 │ 0 │ ┌───┬───┐ └───┴───┴───┴───┘ │ 6 │ 7 │ ← slice 1 ↑ kolom │ 8 │ 9 │ baris ↑ │10 │11 │ └───┴───┘ Akses: arr[i] Akses: arr[row, col] Akses: arr[slice, row, col]
Operasi Vektorisasi
Operasi dilakukan elemen-per-elemen tanpa loop eksplisit. Ini yang membuat NumPy cepat.
Ilustrasi: Memahami Axis
m = array([[1, 2, 3],
[4, 5, 6]])
shape (2, 3)
↑ ↑
axis=0 axis=1
axis=0 → gerak turun (per kolom) axis=1 → gerak mendatar (per baris)
↓ →
[1+4, 2+5, 3+6] [1+2+3, 4+5+6]
= [5, 7, 9] = [6, 15]
Cara ingat: axis=N berarti "hilangkan dimensi ke-N"
shape (2,3) → sum(axis=0) → shape (3,) ← dimensi-0 hilang
shape (2,3) → sum(axis=1) → shape (2,) ← dimensi-1 hilang
Indexing & Slicing
Broadcasting
Broadcasting memungkinkan operasi antara array dengan bentuk berbeda — NumPy secara otomatis "memperluas" array yang lebih kecil.
Ilustrasi: Cara Broadcasting Bekerja
Matriks (3,3) + Vektor baris (3,) 1 2 3 100 200 300 4 5 6 + ↓ ↓ ↓ → vektor "disalin" ke setiap baris 7 8 9 ──────────── ────────────── 101 202 303 104 205 306 107 208 309 Matriks (3,3) + Vektor kolom (3,1) 1 2 3 10 ─┐ 4 5 6 + 20 ─┤ → vektor "disalin" ke setiap kolom 7 8 9 30 ─┘ ──────────── ────────────── 11 12 13 24 25 26 37 38 39 Aturan: dimensi yang tidak cocok harus salah satunya = 1 (3,3) + (3,) → (3,3) + (1,3) ✓ valid (3,3) + (3,1) → sama-sama 3 di axis-0, 1 vs 3 di axis-1 ✓ valid (3,3) + (4,) → 3 ≠ 4, bukan 1 ✗ error!
Reshape & Transpose
Contoh Praktis: Normalisasi Data
Dalam machine learning, fitur sering perlu dinormalisasi. Ini contoh min-max scaling murni dengan NumPy:
matriks[0] adalah baris pertama, bukan kolom. Jika Anda berasal dari MATLAB/R, ini sering membingungkan.2.3 Pandas: Manipulasi Data
Pandas dibangun di atas NumPy. Jika NumPy adalah "array mentah", maka Pandas adalah "spreadsheet yang bisa diprogram" — lengkap dengan label baris, label kolom, dan tipe data per kolom.
Ilustrasi: Series vs DataFrame
pd.Series — 1D, punya index index → 0 1 2 3 ┌────┬────┬────┬────┐ nama │Budi│Ani │Citra│Dedi│ └────┴────┴────┴────┘ dtype: object pd.DataFrame — 2D, punya index + columns nama usia gaji bagian index ↓ ┌──────┬─────┬───────┬──────────┐ 0 │ Budi │ 25 │ 50jt │ Teknik │ 1 │ Ani │ 30 │ 65jt │ Marketing│ 2 │ Citra│ 35 │ 80jt │ Teknik │ 3 │ Dedi │ 28 │ 55jt │ Marketing│ └──────┴─────┴───────┴──────────┘ ↑ columns (setiap kolom = 1 Series)
Membuat DataFrame
Inspeksi Cepat
Lima perintah pertama yang selalu dijalankan setelah memuat data:
Contoh Output: df.describe()
usia gaji
count 4.000000 4.000000e+00
mean 29.500000 6.250000e+07
std 4.358899 1.320475e+07
min 25.000000 5.000000e+07
25% 27.000000 5.375000e+07
50% 29.000000 6.000000e+07
75% 32.000000 7.000000e+07
max 35.000000 8.000000e+07
Kolom non-numerik (nama, bagian) tidak ditampilkan kecuali menggunakan include='all'.
Seleksi & Filtering
Ilustrasi: .loc vs .iloc
nama usia gaji
index ↓
0 Budi 25 50M .loc[0:2] → baris index 0, 1, 2 (inklusif)
1 Ani 30 65M .iloc[0:2] → baris posisi 0, 1 (eksklusif)
2 Citra 35 80M
3 Dedi 28 55M
Aturan praktis:
• Gunakan .loc saat kerja dengan label/nama
• Gunakan .iloc saat kerja dengan posisi angka
• Selalu gunakan salah satu — hindari df[baris, kolom] langsung (bisa ambigu)
Menambah & Mengubah Kolom
GroupBy — Split-Apply-Combine
Pola ini adalah jantung analisis agregasi. Bayangkan seperti pivot table di Excel, tapi jauh lebih powerful.
Ilustrasi: Mekanisme GroupBy
DATA ASLI Budi Teknik 50M Ani Marketing 65M Citra Teknik 80M Dedi Marketing 55M ↓ SPLIT — pisahkan berdasarkan 'bagian' ┌─────────────────┐ ┌─────────────────┐ │ Teknik │ │ Marketing │ │ Budi 50M │ │ Ani 65M │ │ Citra 80M │ │ Dedi 55M │ └────────┬────────┘ └────────┬────────┘ ↓ ↓ ↓ APPLY — hitung mean per grup ↓ ↓ 65M 60M ↓ ↓ ↓ COMBINE — gabungkan hasil ↓ ↓ ┌──────────────┬───────────┐ │ bagian │ gaji_mean │ ├──────────────┼───────────┤ │ Marketing │ 60000000 │ │ Teknik │ 65000000 │ └──────────────┴───────────┘
Sorting & Ranking
Kolom Kategorikal: Value Counts & Crosstab
df[df['kolom'] == x] berkali-kali. Gunakan .groupby() atau .pivot_table() untuk agregasi, dan .query() untuk filtering yang kompleks.2.4 Data I/O
Data science dimulai dan berakhir dengan membaca serta menulis data. Pandas mendukung puluhan format — berikut yang paling penting.
Membaca Data
Menulis Data
Perbandingan Format File
Format Baca Tulis Ukuran Tipe Data Kapan Pakai ───────────────────────────────────────────────────────────────────────────────── CSV Lambat Lambat Besar Hilang Interoperabilitas Parquet Cepat Cepat Kecil Dipertahankan Pipeline perantara Excel Sedang Sedang Sedang Hilang Laporan ke bisnis JSON Sedang Sedang Besar Hilang API / web SQLite Cepat Cepat Kecil Dipertahankan Aplikasi / query kompleks Rekomendasi: CSV untuk input/output awal, Parquet untuk cache perantara.
Pola Praktis: Chunked Reading
Jika file CSV lebih besar dari RAM, baca per chunk:
.parquet untuk penyimpanan perantara — 5-10× lebih cepat dibaca dari CSV, menjaga tipe data (tanggal tetap tanggal, integer tetap integer), dan kompresi ~75% lebih kecil. Satu-satunya kelemahan: tidak bisa dibuka langsung di Notepad.2.5 Pola-Pola Penting
Pola-pola berikut muncul di hampir setiap proyek data science. Kuasai ini, dan Anda bisa menangani 80% kasus manipulasi data.
Pola 1: Apply — Transformasi Kolom
.apply() sebenarnya adalah loop yang disamarkan — tidak secepat operasi vektorisasi. Gunakan np.where(), .str accessor, atau operasi aritmatika langsung jika memungkinkan.Pola 2: Menangani Data Hilang (Missing Values)
Ilustrasi: Strategi Menangani NaN
Data asli: [25, NaN, 35, NaN, 28, 30] dropna() → [25, 35, 28, 30] baris hilang, bisa bikin bias fillna(mean) → [25, 29.5, 35, 29.5, 28, 30] mean = (25+35+28+30)/4 fillna(med) → [25, 28.5, 35, 28.5, 28, 30] median lebih aman dari outlier ffill() → [25, 25, 35, 35, 28, 30] cocok untuk time series interpolate()→ [25, 30, 35, 31.5, 28, 30] linear antara titik Kapan pakai apa: • < 5% NaN & acak → dropna aman • Numerik, ada outlier → fillna(median) • Time series → ffill() atau interpolate() • Kategorikal → fillna(mode) atau "Unknown"
Pola 3: Operasi String
Pola 4: Merge & Join
Sama seperti SQL JOIN — menggabungkan DataFrame berdasarkan key.
Ilustrasi: Jenis-Jenis Join
df_karyawan (LEFT) df_gaji (RIGHT) ┌────┬───────┐ ┌────┬──────┐ │ id │ nama │ │ id │ gaji │ ├────┼───────┤ ├────┼──────┤ │ 1 │ Budi │ │ 1 │ 50 │ │ 2 │ Ani │ │ 2 │ 65 │ │ 3 │ Citra │ │ 5 │ 90 │ │ 4 │ Dedi │ └────┴──────┘ └────┴───────┘ INNER (how='inner') LEFT (how='left') ┌────┬──────┬──────┐ ┌────┬───────┬──────┐ │ id │ nama │ gaji │ │ id │ nama │ gaji │ ├────┼──────┼──────┤ ├────┼───────┼──────┤ │ 1 │ Budi │ 50 │ │ 1 │ Budi │ 50 │ │ 2 │ Ani │ 65 │ │ 2 │ Ani │ 65 │ └────┴──────┴──────┘ │ 3 │ Citra │ NaN │ │ 4 │ Dedi │ NaN │ RIGHT (how='right') └────┴───────┴──────┘ ┌────┬───────┬──────┐ │ id │ nama │ gaji │ OUTER (how='outer') ├────┼───────┼──────┤ ┌────┬───────┬──────┐ │ 1 │ Budi │ 50 │ │ id │ nama │ gaji │ │ 2 │ Ani │ 65 │ ├────┼───────┼──────┤ │ 5 │ NaN │ 90 │ │ 1 │ Budi │ 50 │ └────┴───────┴──────┘ │ 2 │ Ani │ 65 │ │ 3 │ Citra │ NaN │ │ 4 │ Dedi │ NaN │ │ 5 │ NaN │ 90 │ └────┴───────┴──────┘
Pola 5: Pivot Table & Melt
Pola 6: Method Chaining
Alih-alih membuat variabel perantara, rantai operasi bersama. Lebih readable dan mengurangi variabel sementara.
( ) untuk membungkus chain agar bisa pindah baris tanpa backslash. Dan gunakan lambda d: di dalam .assign() untuk merujuk ke DataFrame yang sedang dibangun, bukan DataFrame asli.2.6 Latihan Praktik
Terapkan semua konsep di atas ke dataset nyata. Kerjakan secara berurutan — setiap langkah membangun di atas yang sebelumnya.
📌 Dataset: Titanic (Seaborn built-in)
Latihan 1 — Eksplorasi Awal
Jawab pertanyaan berikut (tanpa melihat kunci jawaban):
- Berapa jumlah baris dan kolom?
- Kolom mana yang memiliki missing values, dan berapa persennya?
- Berapa rata-rata umur penumpang?
- Berapa banyak penumpang di setiap kelas (pclass)?
Lihat kunci jawaban
Latihan 2 — GroupBy & Agregasi
Hitung tingkat keselamatan (survived.mean()) berdasarkan:
- Kelas (
pclass) - Jenis kelamin (
sex) - Kombinasi kelas dan jenis kelamin
Lihat kunci jawaban
Latihan 3 — Imputasi Cerdas
Isi missing value di kolom age dengan median per kelas (bukan median keseluruhan). Mengapa ini lebih baik?
Lihat kunci jawaban
Latihan 4 — Method Chaining Challenge
Dalam satu chain, buat DataFrame yang berisi: penumpang perempuan kelas 1 atau 2 yang selamat, dengan kolom tambahan age_group (Anak <18, Dewasa 18-60, Lansia >60), diurutkan berdasarkan umur menurun.
Lihat kunci jawaban
Cheat Sheet: Bab 2
NUMPY PANDAS np.array([1,2,3]) df = pd.DataFrame({'a':[1,2]}) np.zeros((3,4)) / np.ones((2,3)) df.head() / df.info() / df.describe() np.arange(0,10,2) / np.linspace() df['kolom'] / df[['a','b']] arr.shape / arr.dtype / arr.ndim df.loc[row, col] / df.iloc[pos] arr.sum(axis=0) df[df['x']>5] / df.query('x>5') arr[mask] df.groupby('g')['v'].mean() np.where(cond, a, b) df.merge(a, b, on='key', how='left') arr.reshape(3,-1) / arr.T pd.concat([a,b], axis=0) DATA I/O CLEANING pd.read_csv('f.csv') df.isnull().sum() pd.read_parquet('f.parquet') df.fillna(median) / df.dropna() df.to_parquet('f.parquet') df['col'].str.strip().str.upper() df.rename(columns={'old':'new'}) df.drop(columns=['x'])