Hampir semua laporan data memuat pertanyaan frekuensi: berapa transaksi untuk tiap kategori produk, berapa mahasiswa yang memperoleh nilai A, atau kandidat mana yang paling banyak dipilih dalam pemungutan suara. NumPy menyediakan tiga alat counting dengan karakter yang berbeda, dan memilih alat yang tepat bergantung pada jenis data yang kita miliki.

FungsiInput yang cocokHasil
np.bincountbilangan bulat non-negatifarray frekuensi, satu sel untuk tiap nilai dari 0 sampai maksimum
np.unique(..., return_counts=True)nilai apa pun, termasuk string dan floatnilai unik terurut beserta frekuensinya
np.histogramdata numerik, biasanya kontinujumlah data per bin beserta tepi bin
np.count_nonzeroarray apa punjumlah elemen yang memenuhi satu kondisi

Tiga fungsi pertama menyelesaikan masalah yang beririsan namun tidak identik. Bagian berikut membedah ketiganya satu per satu, dimulai dari yang paling spesifik.

bincount — Satu Sel untuk Setiap Nilai #

np.bincount menerima array bilangan bulat non-negatif dan mengembalikan array yang panjangnya nilai_maksimum + 1. Elemen ke-i dari hasil adalah banyaknya kemunculan nilai i pada input. Mari kita hitung distribusi kode cabang pada data transaksi:

python
import numpy as np

kode_cabang = np.array([3, 0, 1, 3, 2, 3, 1, 0])

frekuensi = np.bincount(kode_cabang)

print("frekuensi :", frekuensi)
print("cabang 3  :", frekuensi[3])
print("panjang   :", len(frekuensi))

Output yang Dihasilkan:

text
frekuensi : [2 2 1 3]
cabang 3  : 3
panjang   : 4

Yang terjadi di balik layar:

  1. Baris 3: interpreter membuat array int64 berisi delapan kode cabang; nilai terbesarnya 3.
  2. Baris 5 (np.bincount(...)): fungsi menyediakan empat sel (indeks 0 sampai 3) lalu menghitung kemunculan tiap nilai — hasil [2 2 1 3] berarti kode 0 muncul 2 kali, 1 muncul 2 kali, 2 muncul 1 kali, dan 3 muncul 3 kali.
  3. Baris 8 (frekuensi[3]): frekuensi satu nilai cukup diakses lewat indeks biasa; cara ini lebih praktis daripada menulis masker kode_cabang == 3 bila kita membutuhkan banyak nilai sekaligus.

Panjang hasil ditentukan oleh nilai maksimum, bukan oleh jumlah kategori yang semestinya ada. Parameter minlength memaksa output memiliki panjang minimum tertentu:

python
import numpy as np

suara = np.array([1, 3, 2, 1, 1, 3])  # kode kandidat 0 sampai 5

print("tanpa minlength :", np.bincount(suara))
print("minlength=4     :", np.bincount(suara, minlength=4))
print("minlength=6     :", np.bincount(suara, minlength=6))

Output yang Dihasilkan:

text
tanpa minlength : [0 3 1 2]
minlength=4     : [0 3 1 2]
minlength=6     : [0 3 1 2 0 0]

Nilai maksimum 3 membuat panjang alami hasil adalah 4. Pemanggilan dengan minlength=4 tidak mengubah apa pun, sedangkan minlength=6 menambah dua sel bernilai 0 untuk kandidat 4 dan 5 yang belum memperoleh suara.

bincount menolak input di luar spesifikasinya. Nilai negatif memunculkan ValueError, sedangkan array float memunculkan TypeError:

python
import numpy as np

suhu = np.array([3, -1, 2, -1])
harga = np.array([1.5, 2.0, 3.5])

try:
    np.bincount(suhu)
except ValueError as e:
    print("ValueError:", e)

try:
    np.bincount(harga)
except TypeError as e:
    print("TypeError:", e)

Output yang Dihasilkan:

text
ValueError: 'list' argument must have no negative elements
TypeError: Cannot cast array data from dtype('float64') to dtype('int64') according to the rule 'safe'

unique dengan return_counts untuk Nilai Apa Pun #

Bila data bukan bilangan bulat kecil — misalnya nilai ujian pecahan, nama produk, atau bilangan negatif — bincount tidak lagi cocok. Kombinasi np.unique dengan return_counts=True menangani semua jenis data tersebut: fungsi ini mengembalikan pasangan array nilai unik yang terurut dan array frekuensinya.

python
import numpy as np

nilai = np.array([72.5, 88.0, 72.5, 65.0, 88.0, 72.5])

nilai_unik, frekuensi = np.unique(nilai, return_counts=True)

print("nilai unik :", nilai_unik)
print("frekuensi  :", frekuensi)
print("modus      :", nilai_unik[np.argmax(frekuensi)])

Output yang Dihasilkan:

text
nilai unik : [65.  72.5 88. ]
frekuensi  : [1 3 2]
modus      : 72.5

Tiga hal yang perlu kita amati:

  1. Baris 5 (return_counts=True): np.unique mengembalikan dua array — nilai unik dan frekuensinya; tanpa parameter tersebut hanya nilai unik yang dikembalikan.
  2. Baris 7-8: nilai_unik terurut naik (65.0, 72.5, 88.0), dan frekuensi sejajar posisinya: 1, 3, 2.
  3. Baris 9 (np.argmax(frekuensi)): modus diambil dengan mencari posisi frekuensi terbesar — teknik yang sama dibahas pada Chapter min, max, argmin, dan argmax.

histogram untuk Data Kontinu #

Untuk data kontinu seperti tinggi badan atau nilai ujian, kita umumnya tidak menghitung frekuensi per nilai, melainkan per rentang (bin). np.histogram melakukan pengelompokan ini dan mengembalikan dua array: jumlah data per bin dan tepi bin. Perilaku tepinya perlu dipahami dengan tepat:

python
import numpy as np

nilai = np.array([45, 58, 67, 72, 75, 80, 82, 91, 95, 60])

jumlah, tepi = np.histogram(nilai, bins=[0, 60, 75, 85, 100])
print("jumlah:", jumlah)
print("tepi  :", tepi)

jumlah2, tepi2 = np.histogram(nilai, bins=4)
print("jumlah2:", jumlah2)
print("tepi2  :", tepi2)

Output yang Dihasilkan:

text
jumlah: [2 3 3 2]
tepi  : [  0  60  75  85 100]
jumlah2: [1 3 4 2]
tepi2  : [45.  57.5 70.  82.5 95. ]

Membaca hasil tersebut:

  1. Baris 5: bins=[0, 60, 75, 85, 100] mendefinisikan empat bin; jumlah selalu sepanjang len(tepi) - 1.
  2. Baris 7 (tepi): setiap bin bersifat setengah-terbuka [a, b) — nilai 60 jatuh ke bin kedua [60, 75), bukan bin pertama [0, 60). Pengecualian berlaku untuk bin terakhir yang tertutup penuh [85, 100], sehingga nilai 95 tetap terhitung.
  3. Baris 9-11 (bins=4): tanpa daftar tepi, NumPy membagi rentang data (45 sampai 95) menjadi empat bin sama lebar 12.5, sehingga tepinya 45.0, 57.5, 70.0, 82.5, 95.0.

Perbedaan ketiga fungsi kini lengkap: bincount untuk bilangan bulat padat, unique + return_counts untuk nilai apa pun, dan histogram untuk data kontinu yang perlu dikelompokkan ke rentang. Untuk data yang hanya butuh dihitung pada satu kondisi, np.count_nonzero tetap menjadi pilihan paling ringkas.