Pada Chapter Fancy Indexing kita memilih banyak elemen sekaligus dengan menuliskan daftar indeks di dalam tanda kurung siku, misalnya harga[[0, 2, 4]]. Cara ini ringkas, tetapi terikat pada sintaks operator: tidak ada tempat menaruh opsi seperti axis dinamis, penulisan hasil ke array lama, atau kebijakan indeks di luar batas. Untuk kebutuhan semacam itu NumPy menyediakan keluarga fungsi np.take, np.put, np.choose, np.compress, dan np.extract.
Kelimanya bekerja seperti operator pengindeksan — mengambil atau menaruh elemen — tetapi berupa panggilan fungsi dengan opsi lebih kaya. Sebagai benang merah, kita memakai data penjualan tiga kota selama tiga bulan.
np.take: Pemilihan dengan Argumen Eksplisit #
Fungsi np.take(a, indices, axis=None, out=None, mode='raise') mengambil elemen a pada posisi indices. Perbedaannya dengan a[indices]: opsi axis sebagai argumen biasa, penulisan hasil ke array lama lewat out, dan kebijakan indeks di luar batas lewat mode.
import numpy as np
penjualan = np.array([[120, 95, 210],
[80, 110, 60],
[150, 70, 180]])
kota = np.array(["Jakarta", "Bandung", "Surabaya"])
print(np.take(kota, [2, 0]))
print(np.take(penjualan, [1, 2], axis=1))
print(penjualan[:, [1, 2]])Output yang Dihasilkan:
['Surabaya' 'Jakarta']
[[ 95 210]
[110 60]
[ 70 180]]
[[ 95 210]
[110 60]
[ 70 180]]Mari kita bedah:
- Baris 3-5:
penjualanadalah matriks 3x3; satu baris mewakili satu kota sesuai urutankota, dan tiap kolom adalah penjualan satu bulan. - Baris 7:
np.take(kota, [2, 0])tanpaaxismengindeks array satu dimensi secara langsung; hasilnya mengikuti urutan daftar indeks, bukan urutan data. - Baris 8:
axis=1memilih kolom 1 dan 2 dari setiap baris — dua bulan terakhir tiap kota. - Baris 9: padanan fancy indexing memberi hasil yang sama. Bedanya,
axispadanp.takeboleh berasal dari variabel saat program berjalan, sehingga fungsi utilitas bisa menerima axis sebagai parameter.
Mode clip dan wrap untuk Indeks di Luar Batas #
Default mode='raise' memunculkan IndexError untuk indeks di luar batas. mode='clip' memotong indeks ke batas terdekat, sedangkan mode='wrap' mengulang indeks dari awal seperti operasi modulo.
import numpy as np
stok = np.array([12, 7, 20, 5])
indeks = np.array([0, 3, 9])
print(np.take(stok, indeks, mode="clip"))
print(np.take(stok, indeks, mode="wrap"))
try:
print(stok[indeks])
except IndexError as e:
print("IndexError:", e)Output yang Dihasilkan:
[12 5 5]
[12 5 7]
IndexError: index 9 is out of bounds for axis 0 with size 4- Baris 5: pada
mode="clip"indeks 9 dipotong menjadi 3, sehingga nilai 5 (stok terakhir) tampil dua kali. - Baris 6: pada
mode="wrap"indeks 9 dipetakan ke 9 % 4 = 1, sehingga nilai 7 yang diambil. - Baris 8-10: fancy indexing dengan indeks yang sama langsung memunculkan
IndexError; pola try/except menjaga blok tetap selesai.
Mode ini berguna bila indeks merupakan hasil perhitungan dan kita ingin perilaku aman tanpa validasi manual.
np.put dan Argumen out pada np.take #
np.put(a, ind, v, mode='raise') adalah kebalikan dari np.take: fungsi tersebut menaruh nilai v pada posisi ind dan mengubah a langsung (in-place). Indeksnya bersifat flat — array diperlakukan sebagai satu barisan memori, tanpa konsep axis — dan mode menerima pilihan yang sama dengan np.take. Sebaliknya, argumen out pada np.take menulis hasil ke array yang sudah tersedia.
import numpy as np
penjualan = np.array([120, 95, 210, 80, 150])
np.put(penjualan, [1, 3], [99, 88])
print(penjualan)
target = np.empty(3, dtype=np.int64)
np.take(penjualan, [0, 2, 4], out=target, mode="clip")
print(target)Output yang Dihasilkan:
[120 99 210 88 150]
[120 210 150]- Baris 4-5: nilai 99 ditaruh pada indeks 1 dan 88 pada indeks 3; tidak ada array baru yang dibuat, dan perubahan terlihat saat
penjualandicetak. - Baris 7-8:
targetdisiapkan lebih dulu dengan bentuk dan dtype yang cocok; NumPy menulis hasilnp.takelangsung ketargettanpa mengalokasikan array sementara — hemat untuk pemanggilan berulang di dalam loop.
np.choose, np.compress, dan np.extract #
np.choose(indeks, daftar) memilih nilai per elemen dari beberapa array kandidat. Sebagai contoh, pelanggan memilih paket harga: 0 berarti tarif reguler, 1 berarti tarif promo.
import numpy as np
reguler = np.array([15000, 20000, 18000])
promo = np.array([12000, 17500, 15000])
paket = np.array([0, 1, 0])
print(np.choose(paket, [reguler, promo]))Output yang Dihasilkan:
[15000 17500 18000]- Baris 5-6: untuk posisi ke-i,
np.choosemengambil elemen ke-i dari kandidat ke-paket[i]; posisi 0 dan 2 bernilai 0 sehingga diambil darireguler, posisi 1 bernilai 1 sehingga diambil daripromo. Bila nilai pemilih melebihi jumlah kandidat,np.choosememunculkanValueError.
np.compress(kondisi, a, axis) memilih potongan utuh sepanjang axis berdasarkan mask boolean; np.extract(kondisi, a) menggabungkan mask dan pengambilan nilai dalam satu panggilan, hasilnya selalu satu dimensi.
import numpy as np
penjualan = np.array([[120, 95, 210],
[80, 110, 60],
[150, 70, 180]])
pilih_kota = np.array([True, False, True])
print(np.compress(pilih_kota, penjualan, axis=0))
print(np.compress(pilih_kota, penjualan, axis=1))
print(np.extract(penjualan[0] > 100, penjualan[0]))Output yang Dihasilkan:
[[120 95 210]
[150 70 180]]
[[120 210]
[ 80 60]
[150 180]]
[120 210]- Baris 7: mask tiga elemen cocok dengan jumlah baris;
axis=0mempertahankan baris ke-0 dan ke-2 (Jakarta dan Surabaya). - Baris 8:
axis=1menerapkan mask yang sama pada kolom; jumlah baris tidak berubah, hanya kolom ke-1 yang lolos seleksi. - Baris 9:
np.extractmengambil nilai di atas 100 dari baris pertama, hasilnya array satu dimensi.
Ketiganya berbagi ide dengan mask pada Chapter Boolean Indexing: a[a > 100] bekerja seperti np.extract. np.compress lebih pas bila dimensi hasil harus terjaga, karena seleksi dilakukan per axis.
Kapan Memilih yang Mana #
Fancy indexing tetap pilihan utama untuk kode sehari-hari karena ringkas. Keluarga fungsi ini menonjol pada situasi berikut:
| Situasi | Pilihan | Alasan |
|---|---|---|
| Axis ditentukan saat program berjalan | np.take | axis bisa menjadi parameter fungsi |
| Indeks mungkin melebihi batas | np.take(mode=...) | clip dan wrap menangani tanpa error |
| Hasil ditulis ke array lama | np.take(..., out=...) | tanpa alokasi array sementara |
| Mengganti nilai pada posisi tertentu | np.put | in-place dan bekerja pada indeks flat |
| Salah satu dari beberapa array kandidat | np.choose | menggantikan if/else per elemen |
| Baris atau kolom utuh menurut mask | np.compress | seleksi sepanjang axis |
| Elemen lolos kondisi, hasil flat | np.extract | satu panggilan untuk mask dan nilai |
Pemilihan fungsi menjadi soal mencocokkan kebutuhan, bukan menghafal nama.