Setelah data rapi, pertanyaan berikutnya biasanya pencarian: pada posisi berapa suhu pertama kali melebihi 30 derajat? Elemen mana saja yang tidak nol? Di posisi berapa nilai baru harus disisipkan agar daftar harga tetap terurut? NumPy menjawab ketiganya tanpa loop Python: argmax, nonzero/argwhere, dan searchsorted.
Bab ini menutup section Manipulasi dan Penggabungan Array dengan pola yang paling sering dipakai pada pekerjaan data sehari-hari: pipeline filter — susun mask baris, pilih baris yang lolos kondisi, lalu urutkan hasilnya.
Trik argmax untuk Kemunculan Pertama #
np.argmax mengembalikan posisi nilai terbesar pada array. Pada array boolean, nilai terbesar adalah True, sehingga np.argmax(mask) mengembalikan posisi True pertama — trik populer untuk mencari kemunculan pertama suatu kondisi.
import numpy as np
suhu = np.array([27.5, 30.2, 29.8, 31.0, 28.4])
mask = suhu > 30.0
print(mask)
print(np.argmax(mask))
tidak_ada = suhu > 40.0
print(tidak_ada.any(), np.argmax(tidak_ada))Output yang Dihasilkan:
[False True False True False]
1
False 0Penjelasannya:
- Baris 4 (
mask = suhu > 30.0): perbandingan menghasilkan array boolean;30.2dan31.0melampaui ambang, keduanya berada di posisi 1 dan 3. - Baris 6 (
np.argmax(mask)):Truesetara 1 danFalsesetara 0, sehingga nilai maksimum pertama berada di posisi1— yaitu suhu30.2, kemunculan pertama di atas 30 derajat. - Baris 9 (
tidak_ada.any(), np.argmax(tidak_ada)): jebakan terlihat di sini. Ketika tidak ada satu punTrue,tidak_ada.any()bernilaiFalse, tetapinp.argmaxtetap mengembalikan0— posisi elemen pertama, bukan tanda “tidak ditemukan”.
nonzero dan argwhere: Dua Bentuk Hasil #
np.nonzero dan np.argwhere menemukan semua posisi elemen yang tidak nol (atau True). Keduanya memuat informasi yang sama, tetapi bentuk hasilnya berbeda dan masing-masing nyaman untuk keperluan yang berbeda.
import numpy as np
matriks = np.array([
[4, 0, 7],
[0, 9, 0],
])
print(np.nonzero(matriks))
print(np.argwhere(matriks))
print(np.argwhere(matriks).shape)Output yang Dihasilkan:
(array([0, 0, 1]), array([0, 2, 1]))
[[0 0]
[0 2]
[1 1]]
(3, 2)Perbedaan bentuknya:
- Baris 7 (
np.nonzero(matriks)): hasilnya tuple berisi satu array per axis — elemen tak nol berada di baris[0 0 1]dan kolom[0 2 1]. Pasangan array ini siap dipakai untuk fancy indexing, misalnyamatriks[np.nonzero(matriks)]untuk mengambil nilai-nilainya. - Baris 8-9 (
np.argwhere(matriks)): hasilnya array dua dimensi berukuran(3, 2)— tiga elemen tak nol, dua koordinat per elemen. Setiap baris adalah satu koordinat(baris, kolom). - Tiga posisi yang ditemukan:
(0, 0)untuk4,(0, 2)untuk7, dan(1, 1)untuk9.
| Fungsi | Bentuk hasil | Paling nyaman untuk |
|---|---|---|
np.nonzero(a) | tuple berisi array indeks per axis | mengindeks ulang: a[np.nonzero(a)] |
np.argwhere(a) | array 2-D berukuran (n, ndim) | membaca daftar koordinat atau loop per titik |
searchsorted: Posisi Sisip pada Array Terurut #
np.searchsorted mencari posisi di mana nilai baru sebaiknya disisipkan agar array terurut tetap terurut. Pencariannya memakai binary search, sehingga biayanya O(log n) — jauh lebih hemat daripada memeriksa elemen satu per satu pada array besar.
import numpy as np
harga = np.array([5000, 9000, 12000, 20000])
print(np.searchsorted(harga, 11000))
print(np.searchsorted(harga, 9000, side="left"))
print(np.searchsorted(harga, 9000, side="right"))Output yang Dihasilkan:
2
1
2Rinciannya:
- Baris 4:
11000harus masuk pada indeks 2 — di antara9000dan12000— agar urutan tetap menaik. - Baris 5 (
side="left"): untuk nilai yang sudah ada seperti9000,side="left"mengembalikan posisi sebelum elemen yang sama, yaitu indeks 1. Ini perilaku default. - Baris 6 (
side="right"): mengembalikan posisi setelah semua elemen yang sama, yaitu indeks 2. Perbedaan keduanya berguna untuk menghitung isi rentang:searchsorted(harga, 12000, side="right") - searchsorted(harga, 9000, side="left")bernilai 2, yaitu banyaknya elemen pada rentang 9000 hingga 12000.
Pipeline Filter: Mask, Seleksi, lalu Urutkan #
Teknik dari bab-bab section ini bergabung menjadi pola kerja yang paling sering dipakai untuk menyiapkan data: buat mask boolean dari kondisi satu kolom, pilih baris yang lolos, kemudian urutkan hasilnya.
import numpy as np
penjualan = np.array([
[120, 85, 200, 65],
[90, 150, 110, 40],
[175, 60, 95, 130],
])
mask = penjualan[:, 0] > 100
terpilih = penjualan[mask]
print(mask)
print(terpilih)
urutan = np.argsort(terpilih[:, 0])[::-1]
print(terpilih[urutan])Output yang Dihasilkan:
[ True False True]
[[120 85 200 65]
[175 60 95 130]]
[[175 60 95 130]
[120 85 200 65]]Langkah demi langkah:
- Baris 8 (
mask = penjualan[:, 0] > 100): slice:, 0mengambil kolom pertama (produk Buku), lalu perbandingannya menghasilkan mask per baris[ True False True]. - Baris 9 (
terpilih = penjualan[mask]): boolean row mask memilih baris-baris utuh yang mask-nyaTrue; hasilnya array baru dan baris kedua tidak ikut. Detailnya ada pada Chapter Boolean Indexing. - Baris 13 (
urutan = np.argsort(terpilih[:, 0])[::-1]):argsortmengurutkan kolom Buku menaik, lalu[::-1]membaliknya menjadi menurun sehingga175mendahului120. Konsepnya dibahas pada Chapter Sorting Array. - Baris 14 (
terpilih[urutan]): fancy indexing menerapkan urutan tersebut ke seluruh baris, sehingga kolom lain tetap konsisten dengan barisnya. Perilaku ini dijelaskan pada Chapter Fancy Indexing.
Pola mask → seleksi → urutkan adalah jembatan menuju analisis data yang lebih kompleks: ganti kondisi pada Baris 8 dan seluruh pipeline mengikuti tanpa perubahan lain.