1. Pengenalan Pandas
Pandas adalah library Python paling populer untuk manipulasi dan analisis data. Nama "Pandas" berasal dari "Panel Data" β konsep ekonometrika untuk dataset multidimensi. Pandas menyediakan struktur data fleksibel dan cepat yang dirancang untuk bekerja dengan data terstruktur (tabel, CSV, Excel, SQL, dll).
Pandas dibangun di atas NumPy dan menjadi fondasi bagi workflow data science β mulai dari pembersihan data, transformasi, agregasi, hingga persiapan data untuk machine learning.
Mengapa Menggunakan Pandas?
| Keunggulan | Penjelasan |
|---|---|
| DataFrame | Struktur data tabel 2D yang intuitif β seperti spreadsheet tapi jauh lebih powerful |
| Handling Missing Data | Fungsi built-in untuk mendeteksi, mengisi, dan menghapus data kosong |
| Flexible Indexing | Akses data dengan label, posisi, boolean mask, dan kondisi kompleks |
| Group & Aggregate | Kelompokkan data dan hitung statistik dengan satu baris kode |
| Import/Export | Baca dan tulis CSV, Excel, JSON, SQL, Parquet, dan banyak format lain |
| Time Series | Dukungan lengkap untuk data deret waktu β resampling, rolling, shifting |
Dua Struktur Data Utama
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β STRUKTUR DATA PANDAS β β β β Series (1D) DataFrame (2D) β β βββββββββββββ βββββββββββββββββββ β β β Index βValβ β A B C β β β β 0 β 10β β0 10 20 30 β β β β 1 β 20β β1 40 50 60 β β β β 2 β 30β β2 70 80 90 β β β β 3 β 40β βββββββββββββββββββ β β βββββββββββββ β β = Kolom tunggal = Kumpulan Series β β = Seperti kolom Excel = Seperti tabel Excel β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2. Instalasi Pandas
Instalasi dengan pip
# Instal Pandas pip install pandas # Instal bersama library yang sering dipakai pip install pandas numpy matplotlib openpyxl # Cek versi python -c "import pandas; print(pandas.__version__)" # Output: 2.2.2
Import Pandas
# Konvensi import Pandas β selalu gunakan alias 'pd' import pandas as pd import numpy as np print(pd.__version__) # 2.2.2
3. Series
Series adalah struktur data 1D di Pandas β seperti kolom di spreadsheet. Setiap Series memiliki index (label) dan values (data).
import pandas as pd
# Membuat Series dari list
nilai = pd.Series([85, 92, 78, 90, 88])
print(nilai)
# 0 85
# 1 92
# 2 78
# 3 90
# 4 88
# dtype: int64
# Series dengan custom index
nama = ["Budi", "Ani", "Dimas", "Sari", "Rina"]
nilai_ujian = pd.Series([85, 92, 78, 90, 88], index=nama)
print(nilai_ujian)
# Budi 85
# Ani 92
# Dimas 78
# Sari 90
# Rina 88
# dtype: int64
# Mengakses elemen
print(nilai_ujian["Ani"]) # 92 (by label)
print(nilai_ujian[0]) # 85 (by position)
print(nilai_ujian["Budi":"Sari"]) # Slicing by label (inklusif!)
# Operasi pada Series
print(nilai_ujian.mean()) # 86.6 β rata-rata
print(nilai_ujian.max()) # 92
print(nilai_ujian.min()) # 78
print(nilai_ujian.sort_values(ascending=False))
# Ani 92
# Sari 90
# Rina 88
# Budi 85
# Dimas 78
# Series dari dictionary
data = {"Jakarta": 10.5, "Bandung": 8.2, "Surabaya": 9.1, "Medan": 7.8}
populasi = pd.Series(data)
print(populasi)
# Jakarta 10.5
# Bandung 8.2
# Surabaya 9.1
# Medan 7.8
# dtype: float64
# Filtering
print(populasi[populasi > 9])
# Jakarta 10.5
# Surabaya 9.1
4. DataFrame
DataFrame adalah struktur data 2D utama di Pandas β seperti tabel spreadsheet atau SQL table. DataFrame terdiri dari kumpulan Series yang berbagi index yang sama.
Membuat DataFrame
import pandas as pd
# DataFrame dari dictionary
data = {
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Umur": [25, 22, 28, 24, 26],
"Kota": ["Jakarta", "Bandung", "Surabaya", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, 9500000, 8000000, 7800000],
"Departemen": ["IT", "HR", "IT", "Finance", "HR"]
}
df = pd.DataFrame(data)
print(df)
# Nama Umur Kota Gaji Departemen
# 0 Budi 25 Jakarta 8500000 IT
# 1 Ani 22 Bandung 7200000 HR
# 2 Dimas 28 Surabaya 9500000 IT
# 3 Sari 24 Jakarta 8000000 Finance
# 4 Rina 26 Medan 7800000 HR
# Informasi dasar DataFrame
print(df.shape) # (5, 5) β 5 baris, 5 kolom
print(df.columns) # Nama kolom
print(df.dtypes) # Tipe data per kolom
print(df.info()) # Ringkasan lengkap
print(df.describe()) # Statistik deskriptif (numerik)
Inspeksi DataFrame
import pandas as pd
# Membuat sample DataFrame
df = pd.DataFrame({
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Umur": [25, 22, 28, 24, 26],
"Kota": ["Jakarta", "Bandung", "Surabaya", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, 9500000, 8000000, 7800000],
})
# Lihat 5 baris pertama
print(df.head(3))
# Nama Umur Kota Gaji
# 0 Budi 25 Jakarta 8500000
# 1 Ani 22 Bandung 7200000
# 2 Dimas 28 Surabaya 9500000
# Lihat 3 baris terakhir
print(df.tail(3))
# Statistik deskriptif
print(df.describe())
# Umur Gaji
# count 5.000000 5.000000e+00
# mean 25.000000 8.200000e+06
# std 2.236068 8.573214e+05
# min 22.000000 7.200000e+06
# 25% 24.000000 7.800000e+06
# 50% 25.000000 8.000000e+06
# 75% 26.000000 8.500000e+06
# max 28.000000 9.500000e+06
# Unique values
print(df["Kota"].unique()) # ['Jakarta' 'Bandung' 'Surabaya' 'Medan']
print(df["Kota"].nunique()) # 4
print(df["Kota"].value_counts()) # Hitung per kategori
5. Indexing dan Selection
Pandas menyediakan beberapa cara untuk mengakses data: loc (berdasarkan label), iloc (berdasarkan posisi), dan boolean indexing.
import pandas as pd
df = pd.DataFrame({
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Umur": [25, 22, 28, 24, 26],
"Kota": ["Jakarta", "Bandung", "Surabaya", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, 9500000, 8000000, 7800000]
})
# ===== loc β berdasarkan LABEL =====
# df.loc[baris, kolom]
print(df.loc[0]) # Seluruh baris index 0
print(df.loc[0, "Nama"]) # "Budi"
print(df.loc[0:2, ["Nama", "Gaji"]]) # Baris 0-2, kolom Nama & Gaji
# Nama Gaji
# 0 Budi 8500000
# 1 Ani 7200000
# 2 Dimas 9500000
# ===== iloc β berdasarkan POSISI (integer) =====
print(df.iloc[0]) # Baris pertama
print(df.iloc[0, 0]) # "Budi" (baris 0, kolom 0)
print(df.iloc[0:3, 0:2]) # Baris 0-2, kolom 0-1
# ===== Akses kolom =====
print(df["Nama"]) # Series
print(df[["Nama", "Kota"]]) # DataFrame (subset kolom)
print(df.Nama) # Alternatif (jika nama valid)
# ===== Boolean Indexing =====
# Filter baris berdasarkan kondisi
mask = df["Umur"] > 24
print(df[mask])
# Nama Umur Kota Gaji
# 0 Budi 25 Jakarta 8500000
# 2 Dimas 28 Surabaya 9500000
# 4 Rina 26 Medan 7800000
# Multiple kondisi (gunakan & untuk AND, | untuk OR)
filtered = df[(df["Umur"] > 23) & (df["Kota"] == "Jakarta")]
print(filtered)
# Nama Umur Kota Gaji
# 0 Budi 25 Jakarta 8500000
# 3 Sari 24 Jakarta 8000000
6. Filtering dan Sorting
import pandas as pd
df = pd.DataFrame({
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Umur": [25, 22, 28, 24, 26],
"Kota": ["Jakarta", "Bandung", "Surabaya", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, 9500000, 8000000, 7800000]
})
# ===== Sorting =====
# Sort by satu kolom
print(df.sort_values("Gaji"))
# Diurutkan dari gaji terkecil ke terbesar
# Sort descending
print(df.sort_values("Gaji", ascending=False))
# Diurutkan dari gaji terbesar ke terkecil
# Sort by beberapa kolom
print(df.sort_values(["Kota", "Gaji"], ascending=[True, False]))
# ===== Method filter =====
# Filter dengan isin
kota_filter = ["Jakarta", "Bandung"]
print(df[df["Kota"].isin(kota_filter)])
# Filter dengan string methods
print(df[df["Nama"].str.startswith("B")]) # Nama diawali B
# ===== Query method (sintaks lebih bersih) =====
print(df.query("Umur > 24"))
print(df.query("Kota == 'Jakarta' and Gaji > 8000000"))
print(df.query("Umur >= 24 and Umur <= 27"))
# ===== Menambah kolom baru =====
df["Gaji_Bulanan"] = df["Gaji"] / 12
df["Status"] = df["Umur"].apply(lambda x: "Senior" if x >= 26 else "Junior")
print(df)
# Nama Umur Kota Gaji Gaji_Bulanan Status
# 0 Budi 25 Jakarta 8500000 708333.333333 Junior
# 1 Ani 22 Bandung 7200000 600000.000000 Junior
# 2 Dimas 28 Surabaya 9500000 791666.666667 Senior
# 3 Sari 24 Jakarta 8000000 666666.666667 Junior
# 4 Rina 26 Medan 7800000 650000.000000 Senior
7. Groupby dan Aggregasi
groupby() memungkinkan Anda mengelompokkan data berdasarkan kolom tertentu dan menghitung statistik untuk setiap kelompok β pola "Split-Apply-Combine".
import pandas as pd
import numpy as np
df = pd.DataFrame({
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina", "Andi", "Lia", "Dedi"],
"Departemen": ["IT", "HR", "IT", "Finance", "HR", "IT", "Finance", "HR"],
"Kota": ["Jakarta", "Bandung", "Jakarta", "Jakarta", "Medan", "Bandung", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, 9500000, 8000000, 7800000, 8200000, 8800000, 7500000]
})
# ===== Groupby sederhana =====
# Rata-rata gaji per departemen
print(df.groupby("Departemen")["Gaji"].mean())
# Departemen
# Finance 8400000.0
# HR 7500000.0
# IT 8733333.3
# ===== Beberapa aggregasi sekaligus =====
print(df.groupby("Departemen")["Gaji"].agg(["mean", "min", "max", "count"]))
# mean min max count
# Departemen
# Finance 8400000.0 8000000 8800000 2
# HR 7500000.0 7200000 7800000 3
# IT 8733333.3 8200000 9500000 3
# ===== Groupby multi kolom =====
print(df.groupby(["Departemen", "Kota"])["Gaji"].mean())
# Departemen Kota
# Finance Jakarta 8400000.0
# HR Bandung 7200000.0
# Medan 7650000.0
# IT Bandung 8200000.0
# Jakarta 9000000.0
# ===== Custom aggregasi =====
def range_gaji(x):
return x.max() - x.min()
print(df.groupby("Departemen")["Gaji"].agg(
rata_rata="mean",
total="sum",
rentang=range_gaji
))
# rata_rata total rentang
# Departemen
# Finance 8400000 16800000 800000
# HR 7500000 22500000 600000
# IT 8733333 26200000 1300000
# ===== Transform β kembali ke DataFrame asli =====
df["Gaji_vs_Rata2"] = df.groupby("Departemen")["Gaji"].transform(
lambda x: x - x.mean()
)
print(df[["Nama", "Departemen", "Gaji", "Gaji_vs_Rata2"]])
8. Merge, Join, dan Concat
Pandas menyediakan berbagai cara untuk menggabungkan dataset β mirip dengan JOIN di SQL.
Merge (SQL-style Join)
import pandas as pd
# Tabel karyawan
karyawan = pd.DataFrame({
"ID": [1, 2, 3, 4, 5],
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Dept_ID": [101, 102, 101, 103, 102]
})
# Tabel departemen
departemen = pd.DataFrame({
"Dept_ID": [101, 102, 103, 104],
"Dept_Nama": ["IT", "HR", "Finance", "Marketing"]
})
# Inner join (default) β hanya yang cocok
merged = pd.merge(karyawan, departemen, on="Dept_ID")
print(merged)
# ID Nama Dept_ID Dept_Nama
# 0 1 Budi 101 IT
# 1 2 Ani 102 HR
# 2 3 Dimas 101 IT
# 3 4 Sari 103 Finance
# 4 5 Rina 102 HR
# Left join β semua dari tabel kiri
left = pd.merge(karyawan, departemen, on="Dept_ID", how="left")
# Right join β semua dari tabel kanan
right = pd.merge(karyawan, departemen, on="Dept_ID", how="right")
print(right)
# Marketing (Dept_ID=104) ada tapi tanpa karyawan
# Outer join β semua dari kedua tabel
outer = pd.merge(karyawan, departemen, on="Dept_ID", how="outer")
Concat dan Append
import pandas as pd
# Data per bulan
januari = pd.DataFrame({
"Produk": ["Laptop", "Mouse", "Keyboard"],
"Penjualan": [50, 200, 150]
})
februari = pd.DataFrame({
"Produk": ["Laptop", "Monitor", "Mouse"],
"Penjualan": [65, 80, 180]
})
# Concat vertikal (tambah baris)
gabung = pd.concat([januari, februari], ignore_index=True)
print(gabung)
# Produk Penjualan
# 0 Laptop 50
# 1 Mouse 200
# 2 Keyboard 150
# 3 Laptop 65
# 4 Monitor 80
# 5 Mouse 180
# Concat horizontal (tambah kolom)
df_a = pd.DataFrame({"Nama": ["Budi", "Ani"], "Umur": [25, 22]})
df_b = pd.DataFrame({"Kota": ["Jakarta", "Bandung"]})
horizontal = pd.concat([df_a, df_b], axis=1)
print(horizontal)
# Nama Umur Kota
# 0 Budi 25 Jakarta
# 1 Ani 22 Bandung
9. Menangani Missing Data
Data yang hilang (NaN/None) adalah masalah umum dalam analisis data. Pandas menyediakan fungsi lengkap untuk mendeteksi, mengisi, dan menghapus data kosong.
import pandas as pd
import numpy as np
df = pd.DataFrame({
"Nama": ["Budi", "Ani", "Dimas", "Sari", "Rina"],
"Umur": [25, np.nan, 28, 24, np.nan],
"Kota": ["Jakarta", None, "Surabaya", "Jakarta", "Medan"],
"Gaji": [8500000, 7200000, np.nan, 8000000, 7800000]
})
print(df)
# Nama Umur Kota Gaji
# 0 Budi 25.0 Jakarta 8500000.0
# 1 Ani NaN None 7200000.0
# 2 Dimas 28.0 Surabaya NaN
# 3 Sari 24.0 Jakarta 8000000.0
# 4 Rina NaN Medan 7800000.0
# Deteksi missing values
print(df.isnull())
print(df.isnull().sum()) # Jumlah NaN per kolom
# Nama 0
# Umur 2
# Kota 1
# Gaji 1
# Hapus baris yang punya NaN
print(df.dropna())
# Hanya baris tanpa NaN sama sekali
# Hapus baris jika kolom tertentu NaN
print(df.dropna(subset=["Umur"]))
# ISI missing values
df_filled = df.copy()
df_filled["Umur"].fillna(df["Umur"].mean(), inplace=True) # Isi dengan rata-rata
df_filled["Kota"].fillna("Tidak Diketahui", inplace=True) # Isi dengan string
df_filled["Gaji"].fillna(0, inplace=True) # Isi dengan 0
print(df_filled)
# Forward fill dan backward fill
ts = pd.Series([1, np.nan, np.nan, 4, np.nan, 6])
print(ts.ffill()) # [1, 1, 1, 4, 4, 6] β isi dengan nilai sebelumnya
print(ts.bfill()) # [1, 4, 4, 4, 6, 6] β isi dengan nilai setelahnya
10. Import dan Export Data
Salah satu kekuatan terbesar Pandas adalah kemampuan membaca dan menulis berbagai format data dengan mudah.
import pandas as pd
# ===== CSV =====
# Baca CSV
df = pd.read_csv("data.csv")
df = pd.read_csv("data.csv", sep=";", encoding="utf-8")
df = pd.read_csv("data.csv", usecols=["Nama", "Gaji"]) # Pilih kolom
df = pd.read_csv("data.csv", nrows=100) # 100 baris pertama
# Tulis CSV
df.to_csv("output.csv", index=False)
df.to_csv("output.csv", index=False, sep=";")
# ===== Excel =====
# Baca Excel (butuh openpyxl)
df = pd.read_excel("data.xlsx", sheet_name="Sheet1")
df = pd.read_excel("data.xlsx", sheet_name=0) # Sheet pertama
# Tulis Excel
df.to_excel("output.xlsx", index=False, sheet_name="Data")
# Banyak sheet sekaligus
with pd.ExcelWriter("multi_sheet.xlsx") as writer:
df_karyawan.to_excel(writer, sheet_name="Karyawan", index=False)
df_departemen.to_excel(writer, sheet_name="Departemen", index=False)
# ===== JSON =====
df = pd.read_json("data.json")
df.to_json("output.json", orient="records", indent=2, force_ascii=False)
# ===== Clipboard (copy dari spreadsheet) =====
# Salin data dari Excel/Google Sheets, lalu:
# df = pd.read_clipboard()
# ===== SQL =====
# import sqlite3
# conn = sqlite3.connect("database.db")
# df = pd.read_sql("SELECT * FROM karyawan", conn)
# df.to_sql("output_table", conn, if_exists="replace")
# conn.close()
11. Transformasi Data
import pandas as pd
df = pd.DataFrame({
"Nama": ["Budi Santoso", "Ani Lestari", "Dimas Pratama", "Sari Dewi"],
"Email": ["budi@mail.com", "ANI@MAIL.COM", "dimas@mail.com ", " sari@mail.com"],
"Tanggal": ["2024-01-15", "2024-02-20", "2024-03-10", "2024-04-05"],
"Nilai": [85.5, 92.3, 78.1, 90.7]
})
# ===== String methods =====
df["Nama_Depan"] = df["Nama"].str.split().str[0]
df["Email_Bersih"] = df["Email"].str.strip().str.lower()
print(df[["Nama", "Nama_Depan", "Email_Bersih"]])
# ===== DateTime =====
df["Tanggal"] = pd.to_datetime(df["Tanggal"])
df["Tahun"] = df["Tanggal"].dt.year
df["Bulan"] = df["Tanggal"].dt.month
df["Hari"] = df["Tanggal"].dt.day_name()
print(df[["Tanggal", "Tahun", "Bulan", "Hari"]])
# ===== Apply β fungsi custom ke setiap elemen =====
def grade(nilai):
if nilai >= 90: return "A"
elif nilai >= 80: return "B"
elif nilai >= 70: return "C"
else: return "D"
df["Grade"] = df["Nilai"].apply(grade)
print(df[["Nama", "Nilai", "Grade"]])
# ===== Pivot Table =====
data_penjualan = pd.DataFrame({
"Bulan": ["Jan", "Jan", "Feb", "Feb", "Mar", "Mar"],
"Produk": ["Laptop", "Mouse", "Laptop", "Mouse", "Laptop", "Mouse"],
"Penjualan": [50, 200, 65, 180, 70, 220]
})
pivot = data_penjualan.pivot_table(
values="Penjualan",
index="Bulan",
columns="Produk",
aggfunc="sum"
)
print(pivot)
# Produk Laptop Mouse
# Bulan
# Feb 65 180
# Jan 50 200
# Mar 70 220
# ===== Melt β unpivot (wide ke long) =====
df_wide = pd.DataFrame({
"Nama": ["Budi", "Ani"],
"Matematika": [85, 92],
"Fisika": [78, 88],
"Kimia": [90, 85]
})
df_long = pd.melt(df_wide, id_vars=["Nama"], var_name="Mata_Kuliah", value_name="Nilai")
print(df_long)
# Nama Mata_Kuliah Nilai
# 0 Budi Matematika 85
# 1 Ani Matematika 92
# 2 Budi Fisika 78
# 3 Ani Fisika 88
# 4 Budi Kimia 90
# 5 Ani Kimia 85
Gunakan .str accessor untuk operasi string, .dt untuk datetime, dan .apply() untuk fungsi custom. Hindari loop β Pandas dioptimalkan untuk operasi vektor yang jauh lebih cepat!
12. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Pandas: