Mam dużą tablicę numpy, którą muszę manipulować, aby każdy element był zmieniany na 1 lub 0, jeśli warunek zostanie spełniony (będzie później używany jako maska pikseli). W tablicy jest około 8 milionów elementów, a moja obecna metoda zajmuje zbyt dużo czasu dla potoku redukcji:
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
Czy jest jakaś funkcja numpy, która przyspieszyłaby to?
python
arrays
numpy
conditional
ChrisFro
źródło
źródło
mask_data[y,x]==3
?if mask_data[y,x]>=3:
Odpowiedzi:
>>> 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]])
Możesz to skrócić za pomocą:
>>> c = (a < 3).astype(int)
źródło
>>> 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]]) >>>
Zobacz np. Indeksowanie za pomocą tablic logicznych .
źródło
a[a > 3] = -101+a[a > 3]
.a[a > 3] = -101+a[a > 3]
zamiasta[a > 3] += -101
ciebie, najprawdopodobniej napotkasz wyciek pamięci.Najszybciej (i elastycznych) sposobem jest użycie np.where , które wybiera pomiędzy dwoma macierzy zgodnie z maską (tablica wartości rzeczywistych i fałszywych)
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)
który wyprodukuje:
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]]
źródło
a[a<3] = 0
Możesz stworzyć swoją tablicę masek w jednym kroku
mask_data = input_mask_data < 3
Tworzy to tablicę logiczną, która może być następnie używana jako maska pikseli. Zauważ, że nie zmieniliśmy tablicy wejściowej (tak jak w twoim kodzie), ale utworzyliśmy nową tablicę do przechowywania danych maski - zalecałbym zrobienie tego w ten sposób.
>>> 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) >>>
źródło
.astype(int)
lub*1
, ale tablicaTrue
iFalse
jest tak samo dobra, jak jest.Nie jestem pewien, czy zrozumiałem Twoje pytanie, ale jeśli napiszesz:
mask_data[:3, :3] = 1 mask_data[3:, 3:] = 0
Spowoduje to, że wszystkie wartości danych maski, których indeksy x i y są mniejsze niż 3, będą równe 1, a wszystkie pozostałe będą równe 0
źródło