Saya memiliki array numpy besar yang perlu saya manipulasi sehingga setiap elemen diubah menjadi 1 atau 0 jika suatu kondisi terpenuhi (akan digunakan sebagai topeng piksel nanti). Ada sekitar 8 juta elemen dalam array dan metode saya saat ini membutuhkan waktu terlalu lama untuk pipeline reduksi:
for (y,x), value in numpy.ndenumerate(mask_data):
if mask_data[y,x]<3: #Good Pixel
mask_data[y,x]=1
elif mask_data[y,x]>3: #Bad Pixel
mask_data[y,x]=0
Apakah ada fungsi numpy yang akan mempercepat ini?
python
arrays
numpy
conditional
ChrisFro
sumber
sumber
mask_data[y,x]==3
?if mask_data[y,x]>=3:
Jawaban:
>>> import numpy as np >>> a = np.random.randint(0, 5, size=(5, 4)) >>> a array([[4, 2, 1, 1], [3, 0, 1, 2], [2, 0, 1, 1], [4, 0, 2, 3], [0, 0, 0, 2]]) >>> b = a < 3 >>> b array([[False, True, True, True], [False, True, True, True], [ True, True, True, True], [False, True, True, False], [ True, True, True, True]], dtype=bool) >>> >>> c = b.astype(int) >>> c array([[0, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1], [0, 1, 1, 0], [1, 1, 1, 1]])
Anda dapat mempersingkatnya dengan:
>>> c = (a < 3).astype(int)
sumber
>>> a = np.random.randint(0, 5, size=(5, 4)) >>> a array([[0, 3, 3, 2], [4, 1, 1, 2], [3, 4, 2, 4], [2, 4, 3, 0], [1, 2, 3, 4]]) >>> >>> a[a > 3] = -101 >>> a array([[ 0, 3, 3, 2], [-101, 1, 1, 2], [ 3, -101, 2, -101], [ 2, -101, 3, 0], [ 1, 2, 3, -101]]) >>>
Lihat, misalnya, Mengindeks dengan array boolean .
sumber
a[a > 3] = -101+a[a > 3]
.a[a > 3] = -101+a[a > 3]
bukana[a > 3] += -101
Anda kemungkinan besar akan kebocoran memori wajah.Cara tercepat (dan paling fleksibel) adalah dengan menggunakan np.where , yang memilih antara dua larik sesuai dengan topeng (larik nilai benar dan salah):
import numpy as np a = np.random.randint(0, 5, size=(5, 4)) b = np.where(a<3,0,1) print('a:',a) print() print('b:',b)
yang akan menghasilkan:
a: [[1 4 0 1] [1 3 2 4] [1 0 2 1] [3 1 0 0] [1 4 0 1]] b: [[0 1 0 0] [0 1 0 1] [0 0 0 0] [1 0 0 0] [0 1 0 0]]
sumber
a[a<3] = 0
Anda dapat membuat array topeng Anda dalam satu langkah seperti ini
mask_data = input_mask_data < 3
Ini membuat array boolean yang kemudian bisa digunakan sebagai topeng piksel. Perhatikan bahwa kami belum mengubah array input (seperti dalam kode Anda) tetapi telah membuat array baru untuk menyimpan data mask - Saya akan merekomendasikan melakukannya dengan cara ini.
>>> input_mask_data = np.random.randint(0, 5, (3, 4)) >>> input_mask_data array([[1, 3, 4, 0], [4, 1, 2, 2], [1, 2, 3, 0]]) >>> mask_data = input_mask_data < 3 >>> mask_data array([[ True, False, False, True], [False, True, True, True], [ True, True, False, True]], dtype=bool) >>>
sumber
.astype(int)
atau*1
, tetapi array dariTrue
danFalse
sama baiknya dengan itu.Saya tidak yakin saya mengerti pertanyaan Anda, tetapi jika Anda menulis:
mask_data[:3, :3] = 1 mask_data[3:, 3:] = 0
Ini akan membuat semua nilai data mask yang indeks x dan y kurang dari 3 menjadi sama dengan 1 dan sisanya sama dengan 0
sumber