6.12. Seleksi dan penataan ulang#
Reduksi menciutkan array menjadi skalar atau hasil berperingkat lebih rendah. Seleksi mencakup operasi yang memilih elemen mana yang bertahan dan di mana mereka berakhir: pilihan kondisional, pemotongan, pengurutan, pencarian indeks, pengurutan ulang sepanjang sebuah sumbu.
6.12.1. Pilihan kondisional#
where() mengembalikan array yang mengambil elemen dari x di mana kondisinya benar dan dari y sebaliknya. Ketiga operand di-broadcast bersama-sama:
a = np.array([1, 2, 3, 4, 5], dtype=np.float)
np.where(a < 3, a, 0.0)
# array([1.0, 2.0, 0.0, 0.0, 0.0])
Ini adalah alat yang tepat untuk operasi "if/else per elemen" tanpa menulis loop Python.
clip() adalah singkatan dari maximum(lo, minimum(a, hi)) -- jenuhkan nilai ke dalam sebuah rentang:
np.clip(a, 2.0, 4.0)
# array([2.0, 2.0, 3.0, 4.0, 4.0])
maximum() dan minimum() mengambil dua operand dan mengembalikan yang lebih besar / lebih kecil per elemen:
np.maximum(a, 3.0)
np.minimum(a, np.array([5, 4, 3, 2, 1]))
6.12.2. Menemukan indeks#
nonzero() mengembalikan koordinat setiap elemen bukan-nol, dibagi menjadi satu array indeks per dimensi. Untuk input 2-D, hasilnya adalah tuple dari dua array: yang pertama berisi indeks baris, yang kedua berisi indeks kolom. Memasangkan keduanya secara kolom memberikan (row, col) dari setiap posisi bukan-nol:
m = np.array([[0, 2, 0],
[3, 0, 0]], dtype=np.float)
np.nonzero(m)
# (array([0, 1], dtype=uint16), array([1, 0], dtype=uint16))
Entri bukan-nol dalam m adalah m[0, 1] = 2 dan m[1, 0] = 3. Array pertama yang dikembalikan [0, 1] memberikan indeks barisnya; yang kedua [1, 0] memberikan indeks kolomnya. Membaca kedua array berdampingan memulihkan posisi (0, 1) dan (1, 0).
Dua reduksi juga menghasilkan indeks:
argmin()/argmax()-- indeks dari elemen terkecil / terbesar.argsort()-- array integer yang akan mengurutkan input sepanjang sumbu yang diberikan (default ke yang terakhir):a = np.array([40, 10, 30, 20], dtype=np.uint8) idx = np.argsort(a) # array([1, 3, 2, 0], dtype=uint16) a[idx] # array([10, 20, 30, 40])
argsortselalu mengembalikanuint16; array yang diurutkan karena itu tidak boleh memiliki lebih dari 65.535 elemen pada sumbu yang diurutkan.
bincount() menghitung kemunculan setiap integer non-negatif dalam input uint8 / uint16 1-D:
histogram = np.bincount(np.array([0, 1, 1, 2, 2, 2], dtype=np.uint8))
# array([1, 2, 3], dtype=uint16)
Berguna untuk membangun histogram dari nilai piksel integer kecil tanpa menulis loop Python.
6.12.3. Pengurutan dan penataan ulang#
sort() mengembalikan salinan array yang diurutkan sepanjang sumbu yang diberikan (terakhir secara default). Gunakan sort() langsung pada array untuk versi in-place:
np.sort(np.array([3, 1, 2], dtype=np.float))
# array([1.0, 2.0, 3.0])
flip() membalikkan urutan sepanjang sumbu yang diberikan (setiap sumbu ketika tidak ada axis yang diteruskan):
np.flip(np.array([1, 2, 3, 4]))
# array([4, 3, 2, 1])
roll() menggeser elemen secara siklik sebesar jumlah yang diberikan. Berguna untuk mengimplementasikan shift register bergaya ring-buffer:
np.roll(np.array([1, 2, 3, 4]), 1)
# array([4, 1, 2, 3])
take() adalah bentuk eksplisit dari fancy indexing -- pilih elemen pada indeks yang sewenang-wenang:
a = np.array([10, 20, 30, 40, 50], dtype=np.uint8)
np.take(a, [0, 2, 4])
# array([10, 30, 50], dtype=uint8)
6.12.4. Penyaringan dan pengeditan struktural#
compress() adalah bentuk eksplisit dari pengindeksan boolean -- kembalikan irisan a yang dipilih oleh kondisi boolean:
a = np.array([10, 20, 30, 40], dtype=np.uint8)
np.compress(a > 15, a)
# array([20, 30, 40], dtype=uint8)
delete() mengembalikan salinan dengan entri pada indeks yang diberikan dihapus:
a = np.array([10, 20, 30, 40, 50], dtype=np.uint8)
np.delete(a, [1, 3])
# array([10, 30, 50], dtype=uint8)
diff() mengembalikan perbedaan maju diskrit ke-n dari array sepanjang sebuah sumbu. Digunakan untuk menghitung perubahan orde pertama antara sampel yang berdekatan:
samples = np.array([1, 3, 6, 10, 15], dtype=np.float)
np.diff(samples)
# array([2.0, 3.0, 4.0, 5.0])
6.12.5. Biaya setiap operasi#
Hampir setiap fungsi di halaman ini mengembalikan array yang baru dialokasikan. Dua pengecualian:
sort()mengurutkan di tempat; fungsi bebassort()mengembalikan salinan yang diurutkan.take()menerima kata kunciout=untuk menulis ke dalam buffer yang sudah ada.
Dalam loop yang berjalan berkali-kali per detik, lebih baik menggunakan sort() in-place dan menggunakan kembali buffer yang sudah dialokasikan di tempat lain. Mask boolean sendiri dialokasikan setiap kali perbandingan dijalankan -- bangun mask sekali dan gunakan kembali di seluruh operasi daripada membangunnya kembali di dalam setiap iterasi.