Ringkasan dataset pada chapter sebelumnya memperlihatkan kolom kategorikal lewat baris top dan freq. Kini kita bedah jenis kolom itu secara menyeluruh: berapa kali setiap kategori muncul, berapa proporsinya, dan bagaimana dua kolom kategorikal saling bertaut. Analisis frekuensi adalah teknik paling sederhana sekaligus paling sering dipakai dalam praktik — mayoritas pertanyaan bisnis harian (“menu apa yang paling laku?”, “pelanggan membayar pakai apa?”) dijawab oleh hitungan kemunculan, bukan oleh model rumit.

Frekuensi dan Proporsi dengan value_counts #

Alat utamanya adalah value_counts(): menghitung berapa kali setiap nilai muncul pada satu kolom. Kita memakai catatan 20 pesanan Toko Kopi Kita dari dua cabang:

python
import pandas as pd

pesanan = pd.DataFrame({
    "menu": ["kopi susu"] * 9 + ["teh tawar"] * 7 + ["matcha latte"] * 4,
    "kota": ["Bandung", "Surabaya", "Bandung", "Bandung", "Surabaya"] * 4,
})

print(pesanan["menu"].value_counts())
print()
print(pesanan["menu"].value_counts(normalize=True))

Output yang Dihasilkan:

text
menu
kopi susu       9
teh tawar       7
matcha latte    4
Name: count, dtype: int64

menu
kopi susu       0.45
teh tawar       0.35
matcha latte    0.20
Name: proportion, dtype: float64

Mari kita baca keluarannya:

  1. value_counts() mengembalikan Series yang terurut menurun: kopi susu muncul 9 kali, teh tawar 7 kali, matcha latte 4 kali. Nama kolom hasilnya adalah count.
  2. normalize=True mengubah hitungan menjadi proporsi terhadap total: 9/20 = 0,45; 7/20 = 0,35; 4/20 = 0,20 — kolom hasilnya bernama proportion. Ketiganya berjumlah 1,00 sehingga terbaca langsung sebagai pecahan dari keseluruhan.
  3. Proporsi lebih jujur daripada hitungan mentah saat membandingkan kelompok yang berbeda ukuran. “Kopi susu terjual 9 gelas” berarti berbeda pada data 20 pesanan dan pada data 2.000 pesanan; “45% pesanan adalah kopi susu” berarti tetap sama di keduanya.

Urutan bawaan value_counts() menempatkan kategori terbesar di atas — pas untuk pertanyaan “apa yang paling sering?”. Namun ada kalanya kita butuh urutan lain, misalnya urutan abjad untuk laporan, atau hanya beberapa teratas untuk ringkasan singkat:

python
import pandas as pd

# Tabel yang sama dengan blok sebelumnya, dibangun lagi agar blok mandiri.
pesanan = pd.DataFrame({
    "menu": ["kopi susu"] * 9 + ["teh tawar"] * 7 + ["matcha latte"] * 4,
    "kota": ["Bandung", "Surabaya", "Bandung", "Bandung", "Surabaya"] * 4,
})

frekuensi = pesanan["menu"].value_counts()

print("Menurut abjad:")
print(frekuensi.sort_index())
print()
print("Dua menu teratas:")
print(frekuensi.head(2))

Output yang Dihasilkan:

text
Menurut abjad:
menu
kopi susu       9
matcha latte    4
teh tawar       7
Name: count, dtype: int64

Dua menu teratas:
menu
kopi susu    9
teh tawar    7
Name: count, dtype: int64

sort_index() mengurutkan hasil menurut label kategorinya, bukan besarannya — berguna saat pembaca laporan mengharapkan urutan tetap dari waktu ke waktu. head(2) memotong ke dua baris teratas, pola yang nyaman untuk laporan mingguan “dua menu terlaris”. Dalam praktik, kombinasi value_counts().head(n) adalah salah satu ekspresi pandas yang paling sering diketik.

Tabulasi Silang Dua Kategorikal dengan crosstab #

Satu kolom kategorikal menjawab “berapa banyak tiap kategori”. Dua kolom kategorikal menjawab pertanyaan yang lebih tajam: “apakah pola menu berbeda antar cabang?” Tabulasi silang (cross tabulation) menyusun kedua kolom menjadi satu matriks hitungan — pd.crosstab():

python
import pandas as pd

# Tabel yang sama dengan blok sebelumnya, dibangun lagi agar blok mandiri.
pesanan = pd.DataFrame({
    "menu": ["kopi susu"] * 9 + ["teh tawar"] * 7 + ["matcha latte"] * 4,
    "kota": ["Bandung", "Surabaya", "Bandung", "Bandung", "Surabaya"] * 4,
})

tabel = pd.crosstab(pesanan["menu"], pesanan["kota"], margins=True)
print(tabel)

Output yang Dihasilkan:

text
kota          Bandung  Surabaya  All
menu                                
kopi susu           6         3    9
matcha latte        2         2    4
teh tawar           4         3    7
All                12         8   20

Cara membaca tabel tersebut:

  1. Baris menyatakan menu, kolom menyatakan kota, dan sel menyatakan jumlah pesanan pada kombinasi keduanya — misalnya kopi susu di Bandung tercatat 6 pesanan.
  2. Baris dan kolom All (hasil margins=True) memuat total tiap baris dan kolom: total per menu (9, 4, 7) cocok dengan value_counts() sebelumnya, total per kota adalah 12 Bandung dan 8 Surabaya.
  3. Sel pojok kanan bawah adalah total keseluruhan 20 — pemeriksaan cepat bahwa tidak ada pesanan yang hilang dari tabulasi.

Tabel silang menjadi jendela perbandingan. Bandung mencatat 12 pesanan dan Surabaya 8, sehingga seluruh sel Surabaya wajar lebih kecil. Pertanyaan yang tepat bukan “angka mana yang lebih besar”, melainkan “apakah pola bagiannya serupa” — dan untuk itu kita butuh proporsi di dalam tiap kolom, yang akan kita hitung pada chapter Analisis Data Kategorikal.

Data yang Timpang dan Cara Membacanya #

Satu sisi analisis frekuensi perlu diwaspadai: satu kategori bisa mendominasi begitu kuat sehingga kategori lain nyaris tak terlihat. Misalkan 96 dari 100 pesanan adalah kopi susu — value_counts() tetap sah dihitung, tetapi dua baris kecilnya mudah dibaca sebagai “cukup sering” padahal hanya 4 kemunculan. Dua kebiasaan membaca menyelamatkan kita dari salah tafsir.

Pertama, selalu tampilkan proporsi di samping hitungan. Angka 4 tanpa konteks berbahaya; “4% dari pesanan” langsung jujur. Kedua, perhatikan jumlah data tiap kelompok sebelum menyimpulkan perbedaan antar kelompok. Selisih 1-2 kemunculan antar cabang bisa terjadi begitu saja pada data kecil, tanpa makna apa pun.

Rangkuman #

  • value_counts() menghitung frekuensi tiap kategori, terurut dari yang terbesar; normalize=True mengubahnya menjadi proporsi yang berjumlah 1.
  • sort_index() dan head(n) mengatur tampilan hasil — urutan abjad untuk laporan, potongan teratas untuk ringkasan.
  • pd.crosstab() menyusun dua kolom kategorikal menjadi matriks hitungan; margins=True menambahkan total tiap baris dan kolom sebagai pemeriksaan cepat.
  • Pada kelompok yang tidak sama besar, bandingkan proporsi di dalam kelompok, bukan hitungan mentah antar kelompok.

Frekuensi memberi tahu berapa banyak tiap kategori muncul, tetapi belum memberi tahu bagaimana nilai-nilai menyebar. Berapa kisarannya, berkumpul di mana, dan apakah menumpuk di satu sisi? Pertanyaan-pertanyaan itu dijawab oleh analisis distribusi — materi chapter berikutnya, Analisis Distribusi .

Referensi #

  1. pandas — User Guide
  2. pandas — API Reference: pivot_table