Tujuan Praktikum
Setelah menyelesaikan praktikum ini, mahasiswa mampu:
- Menjelaskan anatomi DataFrame dan Series, serta membuat DataFrame dari berbagai sumber.
-
Memilih data secara presisi menggunakan
.loc(berbasis label) dan.iloc(berbasis posisi). -
Membaca CSV dengan parameter penting, termasuk mengubah kolom
tanggal menjadi tipe
datetime. -
Menyaring data dengan kondisi majemuk (
&,|,~),between(),isin(), metodestr, danquery(). -
Mengurutkan data secara multi-level serta mengambil nilai
ekstrem dengan
nlargest/nsmallest. -
Membangun tabel ringkasan dengan
agg()untuk menemukan produk terlaris, termurah, dan termahal.
Persiapan
Kebutuhan praktikum:
- Akun Google
- Google Colab
- Koneksi internet
- Dataset penjualan.csv (studi kasus Toko Elektronik)
Buat notebook baru bernama
Pertemuan02_NamaAnda.ipynb, lalu jalankan cell
berikut untuk menyiapkan dataset (file dibuat otomatis di
runtime):
data_csv = """tanggal,produk,kategori,qty,harga
2025-01-01,Laptop,Elektronik,2,8500000
2025-01-01,Mouse,Aksesoris,5,150000
2025-01-02,Keyboard,Aksesoris,3,250000
2025-01-02,Monitor,Elektronik,2,2000000
2025-01-03,Printer,Elektronik,1,1500000
2025-01-03,Mouse,Aksesoris,8,150000
2025-02-01,Laptop,Elektronik,1,8500000
2025-02-02,Keyboard,Aksesoris,4,250000
2025-02-03,Monitor,Elektronik,3,2000000
2025-02-03,Mouse,Aksesoris,6,150000
"""
with open("penjualan.csv", "w") as f:
f.write(data_csv)
print("File penjualan.csv siap digunakan.")
Konsep Singkat
Pandas adalah library Python untuk mengolah data berbentuk tabel. Berbeda dengan sekadar menampilkan data, pada pertemuan ini kita belajar mengendalikan data: memilih baris/kolom secara presisi, menyaring dengan banyak syarat sekaligus, dan menyusun ulang urutannya untuk menjawab pertanyaan bisnis.
Series vs DataFrame
Penting membedakan dua istilah ini:
- Series adalah data satu dimensi, setara dengan satu kolom.
- DataFrame adalah tabel dua dimensi, yaitu gabungan beberapa Series.
Saat kita mengambil satu kolom dari DataFrame (misalnya
df["harga"]), hasilnya adalah sebuah
Series.
Anatomi DataFrame
COLUMNS ──► produk harga
+---------+---------+
INDEX 0 ──► | Laptop | 8500000 | ◄── salah satu baris
1 ──► | Mouse | 150000 |
2 ──► | Keyboard| 250000 |
+---------+---------+
▲
VALUES
- Index — label baris (default: 0, 1, 2, ...).
- Columns — label kolom.
- Values — isi datanya.
Hubungan dengan Struktur Data Python
Ingat struktur list of dictionary dari pertemuan dasar? Setiap dictionary adalah satu baris, dan setiap key adalah satu kolom. DataFrame adalah versi "bertenaga" dari struktur itu — dengan ribuan operasi siap pakai.
List of Dictionary (Python) → DataFrame (Pandas) → Tabel (Database)
Langkah 1 - Membuat dan Mengenali DataFrame
Setiap penggunaan Pandas dimulai dengan import.
pd adalah nama panggilan (alias) yang umum dipakai.
import pandas as pd
Series: Pembentuk DataFrame
harga = pd.Series([8500000, 150000, 250000], name="harga")
print(harga)
print("Tipe:", type(harga))
Output:
0 8500000
1 150000
2 250000
Name: harga, dtype: int64
Tipe: <class 'pandas.core.series.Series'>
Aturan penting:df["harga"]menghasilkan Series (satu kolom), sedangkandf[["harga"]](kurung siku ganda) menghasilkan DataFrame (tabel satu kolom). Perbedaan ini menentukan operasi apa yang bisa dilakukan setelahnya.
Membuat DataFrame dari Dictionary
Format: kolom → daftar nilai.
data = {
"produk": ["Laptop", "Mouse", "Keyboard"],
"harga": [8500000, 150000, 250000],
"stok": [10, 50, 30]
}
df_contoh = pd.DataFrame(data)
print(df_contoh)
Output:
produk harga stok
0 Laptop 8500000 10
1 Mouse 150000 50
2 Keyboard 250000 30
Membuat DataFrame dari List of Dictionary
Format: tiap dictionary = satu baris. Inilah jembatan langsung dari struktur data Python ke Pandas.
records = [
{"produk": "Laptop", "harga": 8500000},
{"produk": "Mouse", "harga": 150000},
]
pd.DataFrame(records)
Atribut Struktur
Atribut ditulis tanpa tanda kurung karena hanya membaca informasi, bukan menjalankan perhitungan.
print(df_contoh.shape) # (baris, kolom)
print(df_contoh.columns) # nama kolom
print(df_contoh.dtypes) # tipe data per kolom
print(df_contoh.index) # label baris
Output:
(3, 3)
Index(['produk', 'harga', 'stok'], dtype='object')
produk object
harga int64
stok int64
dtype: object
RangeIndex(start=0, stop=3, step=1)
| Atribut | Fungsi |
|---|---|
df.shape |
(jumlah baris, jumlah kolom) |
df.columns |
Nama-nama kolom |
df.dtypes |
Tipe data tiap kolom |
df.index |
Label baris |
Melihat Sebagian Data
df_contoh.head() # 5 baris pertama
df_contoh.tail() # 5 baris terakhir
df_contoh.sample(2) # 2 baris acak
Langkah 2 - Memilih Data dengan .loc dan .iloc
Ini adalah inti pengendalian data di Pandas. Keduanya memilih baris/kolom, tetapi dengan cara berbeda:
| Pemilih | Berbasis | Contoh | Arti |
|---|---|---|---|
.loc |
label (nama) | df.loc[0, "produk"] |
baris berlabel 0, kolom "produk" |
.iloc |
posisi (angka) | df.iloc[0, 1] |
baris ke-0, kolom ke-1 |
# .iloc — berbasis posisi
print(df_contoh.iloc[0]) # seluruh baris pertama (Series)
print(df_contoh.iloc[0:2]) # dua baris pertama (DataFrame)
print(df_contoh.iloc[0, 1]) # baris 0, kolom 1 -> 8500000
# .loc — berbasis label
print(df_contoh.loc[0, "produk"]) # -> Laptop
print(df_contoh.loc[0:1, ["produk", "harga"]]) # baris 0-1, kolom terpilih
Catatan: Pada.iloc,0:2berarti posisi 0 dan 1 (batas akhir tidak ikut, seperti slicing list). Pada.loc,0:1justru menyertakan label 1. Perbedaan kecil ini sering jadi sumber kebingungan, jadi ingat baik-baik.
Langkah 3 - Membaca CSV dan Menangani Tipe Tanggal
Membaca File CSV
Pada praktik nyata, data datang dalam bentuk file. Fungsi
pd.read_csv() membaca CSV menjadi DataFrame.
import pandas as pd
df = pd.read_csv("penjualan.csv")
df.head()
Output:
tanggal produk kategori qty harga
0 2025-01-01 Laptop Elektronik 2 8500000
1 2025-01-01 Mouse Aksesoris 5 150000
2 2025-01-02 Keyboard Aksesoris 3 250000
3 2025-01-02 Monitor Elektronik 2 2000000
4 2025-01-03 Printer Elektronik 1 1500000
Masalah Tersembunyi: Tanggal Terbaca sebagai Teks
Periksa tipe datanya:
df.dtypes
Output:
tanggal object
produk object
kategori object
qty int64
harga int64
dtype: object
Perhatikan: tanggal bertipe
object (teks biasa), bukan tanggal.
Akibatnya kita tidak bisa mengambil bulan/tahun
atau menghitung selisih hari. Ini masalah nyata yang sering luput.
Solusi: Parameter parse_dates
Beri tahu Pandas bahwa kolom tanggal adalah tanggal
sejak awal pembacaan:
df = pd.read_csv("penjualan.csv", parse_dates=["tanggal"])
print(df.dtypes)
Output:
tanggal datetime64[ns]
produk object
kategori object
qty int64
harga int64
dtype: object
Sekarang komponen tanggal bisa digali lewat akses
.dt:
df["bulan"] = df["tanggal"].dt.month
df[["tanggal", "bulan"]].head(3)
Output:
tanggal bulan
0 2025-01-01 1
1 2025-01-01 1
2 2025-01-02 1
Parameter read_csv Lain yang Berguna
| Parameter | Kegunaan |
|---|---|
parse_dates=[...] |
Mengubah kolom menjadi tipe tanggal |
usecols=[...] |
Membaca hanya kolom tertentu (hemat memori) |
index_col="kolom" |
Menjadikan suatu kolom sebagai index |
sep=";" |
Untuk CSV yang dipisah titik koma (umum di Eropa) |
Menambah Kolom Turunan
df["total"] = df["qty"] * df["harga"]
df.head(3)
Output:
tanggal produk kategori qty harga bulan total
0 2025-01-01 Laptop Elektronik 2 8500000 1 17000000
1 2025-01-01 Mouse Aksesoris 5 150000 1 750000
2 2025-01-02 Keyboard Aksesoris 3 250000 1 750000
Langkah 4 - Menyaring Data (Filtering)
Konsep: Boolean Indexing
Sebuah kondisi pada kolom menghasilkan deretan
True/False untuk tiap baris; DataFrame
kemudian menampilkan baris yang True.
df["qty"] > 4
Output:
0 False
1 True
2 False
3 False
4 False
5 True
6 False
7 False
8 False
9 True
Name: qty, dtype: bool
Kondisi Majemuk
Gabungkan kondisi dengan & (DAN),
| (ATAU), ~ (BUKAN).
Setiap kondisi wajib dibungkus tanda kurung.
# Elektronik DAN qty minimal 2
df[(df["kategori"] == "Elektronik") & (df["qty"] >= 2)]
Output:
tanggal produk kategori qty harga bulan total
0 2025-01-01 Laptop Elektronik 2 8500000 1 17000000
3 2025-01-02 Monitor Elektronik 2 2000000 1 4000000
8 2025-02-03 Monitor Elektronik 3 2000000 2 6000000
| Operator | Arti | Padanan logika Python | |
|---|---|---|---|
& |
DAN | and |
|
| ` | ` | ATAU | or |
~ |
BUKAN | not |
Error umum: Tanpa tanda kurung —df[df["qty"] >= 2 & df["kategori"] == "Elektronik"]— Python salah membaca urutan operasi dan menghasilkan error. Selalu:df[(kondisi1) & (kondisi2)].
Menyaring Rentang Nilai: between()
df[df["harga"].between(200000, 2000000)]
Output:
tanggal produk kategori qty harga bulan total
2 2025-01-02 Keyboard Aksesoris 3 250000 1 750000
3 2025-01-02 Monitor Elektronik 2 2000000 1 4000000
4 2025-01-03 Printer Elektronik 1 1500000 1 1500000
7 2025-02-02 Keyboard Aksesoris 4 250000 2 1000000
8 2025-02-03 Monitor Elektronik 3 2000000 2 6000000
Menyaring dari Daftar: isin()
df[df["produk"].isin(["Laptop", "Monitor"])]
Menyaring Teks: metode .str
df[df["tanggal"].dt.month == 1] # transaksi bulan Januari
df[df["produk"].str.contains("o")] # produk yang mengandung huruf 'o'
Alternatif yang Lebih Bersih: query()
query() memungkinkan kondisi ditulis seperti kalimat
— cocok untuk filter yang panjang.
df.query("kategori == 'Elektronik' and qty >= 2")
Hasilnya identik dengan boolean indexing di atas, tetapi lebih mudah dibaca.
Langkah 5 - Mengurutkan Data (Sorting)
Mengurutkan Satu Kolom
df.sort_values("harga", ascending=False).head()
Output:
tanggal produk kategori qty harga bulan total
0 2025-01-01 Laptop Elektronik 2 8500000 1 17000000
6 2025-02-01 Laptop Elektronik 1 8500000 2 8500000
3 2025-01-02 Monitor Elektronik 2 2000000 1 4000000
8 2025-02-03 Monitor Elektronik 3 2000000 2 6000000
4 2025-01-03 Printer Elektronik 1 1500000 1 1500000
Penting:sort_values()mengembalikan salinan yang terurut dan tidak mengubahdfasli. Untuk menyimpan, tampung ke variabel:df_urut = df.sort_values("harga"). Hindariinplace=Truesaat masih belajar agar data asli tetap utuh.
Mengurutkan Multi-Level
Urutkan berdasarkan kategori (A→Z), lalu di dalam
tiap kategori berdasarkan harga (besar→kecil). Setiap
kolom bisa punya arah urut sendiri.
df.sort_values(["kategori", "harga"], ascending=[True, False])
Mengambil Nilai Ekstrem dengan Cepat
df.nlargest(3, "total") # 3 transaksi dengan total tertinggi
df.nsmallest(3, "harga") # 3 transaksi dengan harga terendah
nlargest/nsmallest lebih ringkas
daripada sort_values(...).head(n) dan langsung
memberi N data teratas/terbawah.
Langkah 6 - Tabel Ringkasan dan Analisis Produk
Daripada menjawab tiap pertanyaan dengan perintah terpisah, kita bangun satu tabel ringkasan per produk, lalu jawab semua pertanyaan dari sana. Pendekatan ini lebih rapi dan mudah dikembangkan.
Persiapan
import pandas as pd
df = pd.read_csv("penjualan.csv", parse_dates=["tanggal"])
df["total"] = df["qty"] * df["harga"]
Membangun Ringkasan dengan agg()
groupby().agg() memungkinkan kita menghitung beberapa
ringkasan sekaligus dan memberi nama kolomnya:
ringkasan = df.groupby("produk").agg(
total_qty=("qty", "sum"),
total_penjualan=("total", "sum"),
jumlah_transaksi=("produk", "count"),
harga_satuan=("harga", "first")
)
print(ringkasan)
Output:
total_qty total_penjualan jumlah_transaksi harga_satuan
produk
Keyboard 7 1750000 2 250000
Laptop 3 25500000 2 8500000
Monitor 5 10000000 2 2000000
Mouse 19 2850000 3 150000
Printer 1 1500000 1 1500000
Satu tabel ini sudah memuat semua yang kita butuhkan.
1. Produk Terlaris (qty terbanyak)
terlaris = ringkasan["total_qty"].idxmax()
print("Produk terlaris:", terlaris, "-", ringkasan.loc[terlaris, "total_qty"], "unit")
Output:
Produk terlaris: Mouse - 19 unit
2. Produk Termurah (harga satuan terendah)
termurah = ringkasan["harga_satuan"].idxmin()
print("Produk termurah:", termurah, "-", ringkasan.loc[termurah, "harga_satuan"])
Output:
Produk termurah: Mouse - 150000
3. Produk Termahal (harga satuan tertinggi)
termahal = ringkasan["harga_satuan"].idxmax()
print("Produk termahal:", termahal, "-", ringkasan.loc[termahal, "harga_satuan"])
Output:
Produk termahal: Laptop - 8500000
Konsep kunci:idxmax()/idxmin()mengembalikan label index (di sini nama produk) yang memiliki nilai tertinggi/terendah. Karena tabel ringkasan ber-indexproduk, jawabannya langsung berupa nama produk — tanpa perlu mengurutkan terlebih dahulu.
Ringkasan Hasil
print("=== ANALISIS PRODUK ===")
print("Terlaris :", ringkasan["total_qty"].idxmax())
print("Termurah :", ringkasan["harga_satuan"].idxmin())
print("Termahal :", ringkasan["harga_satuan"].idxmax())
Output:
=== ANALISIS PRODUK ===
Terlaris : Mouse
Termurah : Mouse
Termahal : Laptop
Temuan untuk didiskusikan: Mouse termurah sekaligus terlaris (19 unit), tetapi penyumbang penjualan rupiah terbesar justru Laptop (Rp25.500.000) meski hanya laku 3 unit. Volume tinggi belum tentu berarti pendapatan tinggi — diskusikan implikasinya bagi pemilik toko.
Pengujian
Periksa hasil praktikum dengan memastikan output sesuai berikut:
-
df.shapesetelah membaca CSV dan menambah kolombulan+totalmenghasilkan(10, 7). -
df.dtypesmenunjukkan kolomtanggalbertipedatetime64[ns]. -
Tabel
ringkasanmemuat 5 baris produk dengantotal_qtyMouse = 19 danharga_satuanLaptop = 8500000. - Hasil analisis: terlaris = Mouse, termurah = Mouse, termahal = Laptop.
Verifikasi cepat secara otomatis:
assert df.shape == (10, 7)
assert ringkasan.loc["Mouse", "total_qty"] == 19
assert ringkasan["harga_satuan"].idxmax() == "Laptop"
print("Semua pengujian lolos.")
Troubleshooting
| Masalah | Penyebab | Solusi |
|---|---|---|
FileNotFoundError: penjualan.csv |
File belum dibuat di runtime aktif | Jalankan ulang cell pada bagian Persiapan |
KeyError: 'nama_kolom' |
Nama kolom salah ketik | Periksa daftar kolom dengan df.columns |
| Filter majemuk menghasilkan error | Lupa tanda kurung tiap kondisi | Tulis df[(kondisi1) & (kondisi2)] |
.dt menghasilkan error |
Kolom tanggal masih bertipe object |
Baca ulang dengan
parse_dates=["tanggal"]
|
| Hasil pengurutan tidak tersimpan | sort_values mengembalikan salinan |
Tampung ke variabel: df2 = df.sort_values(...)
|
Tugas Praktikum
Buat laporan (format PDF) yang berisi:
- Identitas: Nama dan NIM.
- Tabel ringkasan per produk hasil
agg(). - Produk terlaris, termurah, dan termahal.
-
Produk penyumbang penjualan rupiah tertinggi — petunjuk:
ringkasan["total_penjualan"].idxmax(). -
Total penjualan per bulan — petunjuk:
df.groupby(df["tanggal"].dt.month)["total"].sum(). -
Produk terlaris khusus bulan Januari — petunjuk: gabungkan
filter
df["tanggal"].dt.month == 1dengangroupby, laluidxmax(). Bandingkan dengan terlaris keseluruhan. - Kesimpulan dan interpretasi temuan.
Tips: ekspor notebook ke PDF melalui menu File → Print → Save as PDF.
Kesimpulan
Pada pertemuan ini mahasiswa menguasai fondasi Pandas secara
menyeluruh: memahami anatomi DataFrame dan Series, memilih data
presisi dengan .loc/.iloc, membaca CSV
beserta penanganan tipe tanggal, menyaring data dengan kondisi
majemuk hingga query(), dan mengurutkan data secara
multi-level. Puncaknya, mahasiswa membangun tabel ringkasan dengan
agg() untuk menjawab pertanyaan bisnis — produk
terlaris, termurah, dan termahal — serta menafsirkan perbedaan
antara volume dan nilai penjualan. Kemampuan membentuk tabel
ringkasan ini menjadi pijakan untuk visualisasi data pada
pertemuan berikutnya.