Saya memiliki array NumPy 2D dan ingin mengganti semua nilai di dalamnya lebih besar atau sama dengan ambang T dengan 255.0. Sepengetahuan saya, cara yang paling mendasar adalah:
shape = arr.shape
result = np.zeros(shape)
for x in range(0, shape[0]):
for y in range(0, shape[1]):
if arr[x, y] >= T:
result[x, y] = 255
Apa cara paling ringkas dan pythonic untuk melakukan ini?
Apakah ada cara yang lebih cepat (mungkin kurang ringkas dan / atau kurang pythonic) untuk melakukan ini?
Ini akan menjadi bagian dari subroutine penyesuaian level / jendela untuk pemindaian MRI kepala manusia. Array numpy 2D adalah data piksel gambar.
Jawaban:
Saya pikir cara tercepat dan paling ringkas untuk melakukan ini adalah dengan menggunakan pengindeksan NumPy bawaan. Jika Anda memiliki
ndarray
namaarr
, Anda dapat mengganti semua elemen>255
dengan nilaix
sebagai berikut:Saya menjalankan ini pada mesin saya dengan matriks acak 500 x 500, mengganti semua nilai> 0,5 dengan 5, dan butuh rata-rata 7,59 ms.
sumber
arr
, alih-alih membuatresult
array seperti pada OP.A
tetapi membuat array baru?np.array([1,2,3]
)Karena Anda sebenarnya menginginkan array yang berbeda di
arr
manaarr < 255
, dan255
sebaliknya, ini bisa dilakukan dengan mudah:Secara umum, untuk batas bawah dan / atau atas:
Jika Anda hanya ingin mengakses nilai lebih dari 255, atau sesuatu yang lebih rumit, jawaban @ mtitan8 lebih umum, tetapi
np.clip
dannp.minimum
(ataunp.maximum
) lebih baik dan lebih cepat untuk kasus Anda:Jika Anda ingin melakukannya di tempat (yaitu, memodifikasi
arr
alih-alih membuatresult
) Anda dapat menggunakanout
parameternp.minimum
:atau
(
out=
nama bersifat opsional karena argumen dalam urutan yang sama dengan definisi fungsi.)Untuk modifikasi di tempat, pengindeksan boolean mempercepat banyak (tanpa harus membuat dan kemudian memodifikasi salinan secara terpisah), tetapi masih tidak secepat
minimum
:Sebagai perbandingan, jika Anda ingin membatasi nilai Anda dengan minimum dan maksimum, tanpa
clip
Anda harus melakukan ini dua kali, dengan sesuatu sepertiatau,
sumber
a[start:stop:step]
memberi Anda elemen-elemen array daristart
kestop
, tetapi alih-alih setiap elemen, dibutuhkan hanya setiapstep
(jika diabaikan, itu secara1
default) ). Jadi untuk mengatur semua GENAP menjadi nol, Anda bisa melakukannyaa[::2] = 0
Saya pikir Anda dapat mencapai ini dengan tercepat menggunakan
where
fungsi:Misalnya mencari item yang lebih besar dari 0,2 dalam array numpy dan menggantikannya dengan 0:
sumber
Anda dapat mempertimbangkan menggunakan numpy.putmask :
Berikut adalah perbandingan kinerja dengan pengindeksan bawaan Numpy:
sumber
Cara lain adalah dengan menggunakan
np.place
yang melakukan penggantian di tempat dan bekerja dengan array multidimensi:sumber
np.place
juga lebih lambat dibandingkan dengan metode built-in, meskipun sebaliknya diklaim dalam komentar ini .Anda juga dapat menggunakan
&
,|
(dan / atau) untuk lebih banyak fleksibilitas:nilai antara 5 dan 10:
A[(A>5)&(A<10)]
nilai lebih besar dari 10 atau lebih kecil dari 5:
A[(A<5)|(A>10)]
sumber