Array NumPy menghitung cepat, tetapi data nyata jarang sekata. Catatan penjualan Toko Kopi Kita membawa tanggal (teks), nama produk (teks), nama kota (teks), jumlah (bilangan), dan harga (bilangan) dalam satu tabel — dan tabel itulah bentuk data yang paling sering kita terima di dunia kerja. Pandas adalah library yang dibangun untuk tabel: membacanya dari berkas, memeriksanya, memilih bagiannya, menyaring barisnya, dan meringkasnya per kelompok. Pada chapter ini kita berkenalan dengan dua struktur intinya — Series dan DataFrame — lalu mempraktikkan alur kerja lengkap pada berkas penjualan.csv yang berisi 15 transaksi sepekan.
Series dan DataFrame: Satu Kolom dan Satu Tabel #
Series adalah satu kolom berlabel: deret nilai plus daftar label yang disebut index, satu per baris. DataFrame adalah tabel utuh — secara teknis, kumpulan Series yang berbagi index yang sama. Kita buat keduanya secara eksplisit dulu:
import pandas as pd
# Series: satu kolom angka yang setiap barisnya berlabel (index)
jumlah = pd.Series(
data=[85, 51, 28],
index=["kopi susu", "matcha latte", "teh tawar"],
name="terjual (gelas)",
)
print(jumlah)
print()
print("Akses dengan label :", jumlah["matcha latte"])Output yang Dihasilkan:
kopi susu 85
matcha latte 51
teh tawar 28
Name: terjual (gelas), dtype: int64
Akses dengan label : 51Label kiri pada keluaran di atas adalah index dan angka kanannya nilai Series; name menjadi nama kolom saat Series ini dipakai di dalam DataFrame. Akses jumlah["matcha latte"] menuju baris berdasarkan labelnya, bukan berdasarkan posisi — inilah perbedaan paling terasa dibanding array NumPy yang hanya mengenal posisi.
DataFrame paling mudah dibangun dari dictionary — setiap kunci menjadi nama kolom — atau dari list of dictionary yang tiap anggotanya menjadi satu baris:
import pandas as pd
# DataFrame dari dictionary: {nama kolom: daftar nilai}
menu = pd.DataFrame({
"minuman": ["kopi susu", "matcha latte", "teh tawar", "cokelat panas"],
"harga": [24, 28, 20, 30], # ribu rupiah
"volume_ml": [300, 250, 200, 400],
})
print(menu)
print()
# DataFrame dari list of dictionary: satu dictionary per baris
pesanan = pd.DataFrame([
{"produk": "kopi susu", "jumlah": 2},
{"produk": "teh tawar", "jumlah": 1},
])
print(pesanan)Output yang Dihasilkan:
minuman harga volume_ml
0 kopi susu 24 300
1 matcha latte 28 250
2 teh tawar 20 200
3 cokelat panas 30 400
produk jumlah
0 kopi susu 2
1 teh tawar 1Perhatikan kolom paling kiri pada kedua tabel: angka 0, 1, 2, ... adalah index otomatis yang diberikan pandas ketika kita tidak menetapkan label sendiri. Bentuk dictionary cocok saat data tersusun per kolom, sedangkan list of dictionary cocok saat data mengalir per baris — misalnya hasil pembacaan berkas.
Membaca File CSV dengan read_csv #
Sumber data paling umum adalah berkas CSV (comma-separated values): teks dengan satu baris data per baris teks dan tanda koma sebagai pemisah kolom. Kita pakai berkas penjualan.csv berikut — lima kolom, lima belas transaksi pekan 6-12 Januari 2025 di dua cabang:
tanggal,produk,kota,jumlah,harga
2025-01-06,kopi susu,Bandung,12,24000
2025-01-06,matcha latte,Bandung,8,28000
2025-01-06,teh tawar,Bandung,5,20000
2025-01-07,kopi susu,Bandung,15,24000
2025-01-07,teh tawar,Bandung,6,20000
2025-01-08,kopi susu,Surabaya,10,24000
2025-01-08,matcha latte,Surabaya,9,28000
2025-01-09,kopi susu,Surabaya,14,24000
2025-01-09,matcha latte,Surabaya,17,28000
2025-01-09,teh tawar,Surabaya,4,20000
2025-01-10,kopi susu,Bandung,18,24000
2025-01-10,matcha latte,Bandung,7,28000
2025-01-11,kopi susu,Surabaya,16,24000
2025-01-11,teh tawar,Surabaya,13,20000
2025-01-12,matcha latte,Bandung,10,28000Membacanya membutuhkan satu fungsi — pd.read_csv() dengan nama berkas relatif terhadap folder kerja:
import pandas as pd
df = pd.read_csv("penjualan.csv")
print("Bentuk (baris, kolom) :", df.shape)
print(df.head())Output yang Dihasilkan:
Bentuk (baris, kolom) : (15, 5)
tanggal produk kota jumlah harga
0 2025-01-06 kopi susu Bandung 12 24000
1 2025-01-06 matcha latte Bandung 8 28000
2 2025-01-06 teh tawar Bandung 5 20000
3 2025-01-07 kopi susu Bandung 15 24000
4 2025-01-07 teh tawar Bandung 6 20000df adalah nama variabel kebiasaan untuk DataFrame. df.shape memuat ukuran (15, 5) seperti shape pada array NumPy, dan df.head() menampilkan lima baris pertama — cara tercepat memastikan berkas terbaca dengan benar sebelum diproses lebih jauh.
Inspeksi Cepat: info dan describe #
Sebelum menganalisis, kita periksa dulu apa yang sebenarnya kita pegang: berapa baris, kolom apa saja, tipe data apa, dan bagaimana sebaran angkanya. Dua alatnya adalah df.info() dan df.describe():
import pandas as pd
df = pd.read_csv("penjualan.csv")
df.info()
print()
print(df.describe())Output yang Dihasilkan:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15 entries, 0 to 14
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 tanggal 15 non-null object
1 produk 15 non-null object
2 kota 15 non-null object
3 jumlah 15 non-null int64
4 harga 15 non-null int64
dtypes: int64(2), object(3)
memory usage: 732.0+ bytes
jumlah harga
count 15.000000 15.000000
mean 10.933333 24266.666667
std 4.479583 3195.234547
min 4.000000 20000.000000
25% 7.500000 22000.000000
50% 10.000000 24000.000000
75% 14.500000 28000.000000
max 18.000000 28000.000000Mari kita baca keluaran info() baris demi baris:
RangeIndex: 15 entries: 15 baris berindex 0 sampai 14 — cocok denganshapedan berarti tidak ada baris yang gagal dibaca.- Kolom
Non-Null Count: setiap kolom mencatat 15 nilai non-kosong. Kolom yang mencatat kurang dari 15 menandakan adanya missing values — topik besar yang kita bahas tuntas pada bab pembersihan data. - Kolom
Dtype:tanggal,produk, dankotaterbaca sebagaiobject(teks), sedangkanjumlahdanhargasebagaiint64. Pada dasarnya setiap kolom DataFrame adalah array NumPy dengandtypesendiri — itulah jembatan antara kedua library. describe()meringkas hanya kolom numerik:countjumlah data,meanrata-rata,stdsimpangan baku, lalumin, kuartil25%/50%/75%, danmax. Nilai50%adalah median — separuh transaksi menjual 10 gelas atau kurang. Statistik kolomhargaperlu dibaca hati-hati karena hanya ada tiga harga berbeda (20, 24, dan 28 ribu rupiah): rata-ratanya menggambarkan campuran produk yang terjual, bukan harga satu menu tertentu.
Baris memory usage: 732.0+ bytes melaporkan perkiraan pemakaian memori; tanda plus menandakan angka tersebut masih bisa bertambah bila ada kolom bertipe object yang panjang.
Memilih Kolom dan Menyaring Baris dengan Mask Boolean #
Dua kebutuhan paling sering: mengambil sebagian kolom, dan mengambil baris yang memenuhi syarat. Pemilihan kolom memakai kurung siku seperti pada dictionary; penyaringan baris memakai mask boolean — Series berisi True/False yang menentukan baris mana yang lolos:
import pandas as pd
df = pd.read_csv("penjualan.csv")
# 1. Memilih kolom: satu kolom -> Series, beberapa kolom -> DataFrame
print("Produk unik :", df["produk"].unique().tolist())
print(df[["tanggal", "produk", "jumlah"]].head(3))
print()
# 2. Filter baris dengan mask boolean
mask_bandung = df["kota"] == "Bandung"
print("Mask seluruhnya :")
print(mask_bandung.tolist())
print("Baris Bandung :", len(df[mask_bandung]))
print(df[mask_bandung][["tanggal", "produk", "jumlah"]])
print()
# 3. Kombinasi kondisi: & (dan), | (atau) — selalu beri tanda kurung
mask_laris = (df["kota"] == "Surabaya") & (df["jumlah"] >= 14)
print(df[mask_laris][["tanggal", "produk", "jumlah"]])Output yang Dihasilkan:
Produk unik : ['kopi susu', 'matcha latte', 'teh tawar']
tanggal produk jumlah
0 2025-01-06 kopi susu 12
1 2025-01-06 matcha latte 8
2 2025-01-06 teh tawar 5
Mask seluruhnya :
[True, True, True, True, True, False, False, False, False, False, True, True, False, False, True]
Baris Bandung : 8
tanggal produk jumlah
0 2025-01-06 kopi susu 12
1 2025-01-06 matcha latte 8
2 2025-01-06 teh tawar 5
3 2025-01-07 kopi susu 15
4 2025-01-07 teh tawar 6
10 2025-01-10 kopi susu 18
11 2025-01-10 matcha latte 7
14 2025-01-12 matcha latte 10
tanggal produk jumlah
7 2025-01-09 kopi susu 14
8 2025-01-09 matcha latte 17
12 2025-01-11 kopi susu 16Tiga pola pada contoh di atas:
- Pemilihan kolom:
df["produk"]mengembalikan satu Series, sedangkandf[["tanggal", "produk", "jumlah"]]dengan list di dalam kurung mengembalikan DataFrame baru berisi tiga kolom tersebut. Method.unique()memangkas Series menjadi daftar nilai uniknya. - Mask boolean: perbandingan
df["kota"] == "Bandung"menghasilkan Series 15True/False— lima pertamaTrue, lima berikutnyaFalsekarena baris 5 sampai 9 adalah Surabaya, dan seterusnya. Menuliskandf[mask_bandung]berarti “pertahankan baris yangTruesaja”, sehingga tersisa 8 baris Bandung. - Kombinasi kondisi:
(df["kota"] == "Surabaya") & (df["jumlah"] >= 14)menyaring 3 baris — transaksi Surabaya dengan minimal 14 gelas.
Kolom Baru, groupby, dan sort_values #
Alur analisis biasanya ditutup tiga langkah: menambah kolom turunan, meringkas per kelompok, lalu mengurutkan hasilnya. Ketiganya berpatungan pada satu blok berikut — dan angka totalnya akan terasa akrab:
import pandas as pd
df = pd.read_csv("penjualan.csv")
# Kolom baru: pendapatan = jumlah x harga (element-wise, gaya NumPy)
df["pendapatan"] = df["jumlah"] * df["harga"]
# Agregat per produk: total jumlah dan pendapatan
per_produk = df.groupby("produk")[["jumlah", "pendapatan"]].sum()
print(per_produk)
print()
# Lima transaksi dengan jumlah terbanyak
top5 = df.sort_values("jumlah", ascending=False).head(5)
print(top5[["tanggal", "produk", "kota", "jumlah"]])Output yang Dihasilkan:
jumlah pendapatan
produk
kopi susu 85 2040000
matcha latte 51 1428000
teh tawar 28 560000
tanggal produk kota jumlah
10 2025-01-10 kopi susu Bandung 18
8 2025-01-09 matcha latte Surabaya 17
12 2025-01-11 kopi susu Surabaya 16
3 2025-01-07 kopi susu Bandung 15
7 2025-01-09 kopi susu Surabaya 14Mari kita bedah tiga langkahnya:
- Kolom baru:
df["jumlah"] * df["harga"]mengalikan dua Series element-wise — persis perilaku array NumPy pada chapter sebelumnya — dan menugaskannya ke kolompendapatanlangsung menambah kolom baru pada tabel. groupby("produk"): memecah tabel menjadi kelompok per produk, meringkas tiap kelompok dengan.sum()pada kolom["jumlah", "pendapatan"], lalu menggabungkan hasilnya. Totaljumlah85, 51, dan 28 persis angka Series pertama kita di awal chapter; kolompendapatanmenambahkan 85 x 24.000 = 2.040.000 untuk kopi susu, dan seterusnya.sort_values("jumlah", ascending=False): mengurutkan baris dari jumlah terbanyak, lalu.head(5)memotong lima teratas — dipimpin transaksi 18 gelas di Bandung dan 17 gelas matcha latte di Surabaya. Urutan index yang tampak berantakan (10, 8, 12, 3, 7) mengingatkan bahwa index adalah label baris asal, bukan posisi hasil urut.
Rangkuman #
- Series = satu kolom berlabel (index); DataFrame = tabel berisi kumpulan Series berindex sama; keduanya dibangun dari dictionary maupun list of dictionary.
pd.read_csv("berkas.csv")memuat tabel;df.shape,df.head(),df.info(), dandf.describe()adalah paket inspeksi pertama sebelum analisis.df.info()memperlihatkan jumlah baris, kolom,Non-Null Count, danDtypetiap kolom;describe()meringkas kolom numerik dengan mean, std, dan kuartil.- Pemilihan kolom memakai
df["kolom"]dandf[[...]]; penyaringan baris memakai mask booleandf[df["kota"] == "Bandung"], digabung dengan&/|dan tanda kurung. - Kolom baru dihitung element-wise;
groupbymeringkas per kelompok;sort_valuesmengurutkan hasil.
Tabel sudah terbaca, terinspeksi, dan teringkas menjadi angka-angka yang bermakna. Langkah terakhir pada alur kerja Python ini adalah mengubah angka menjadi gambar yang bisa dibaca sekilas oleh mata — mulai dari diagram batang hingga diagram garis. Kita tutup Section dengan library ketiga, matplotlib, pada chapter Dasar Matplotlib .
Referensi #
- Pandas — Getting Started Tutorials — tur resmi pertama: membuat DataFrame, membaca CSV, dan operasi dasar.
- Pandas — pandas.read_csv
— rujukan lengkap parameter
read_csv. - Pandas — DataFrame.groupby — mekanisme pengelompokan dan agregasi.