Mam tablicę 2D NumPy i chciałbym zastąpić w niej wszystkie wartości większe lub równe progowi T o wartości 255.0. Według mojej wiedzy najbardziej fundamentalnym sposobem byłoby:
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
Jaki jest najbardziej zwięzły i pytonowy sposób na zrobienie tego?
Czy istnieje szybszy (być może mniej zwięzły i / lub mniej pytoniczny) sposób na zrobienie tego?
Będzie to część podprogramu regulacji okna / poziomu dla skanów MRI ludzkiej głowy. Tablica numpy 2D to dane pikseli obrazu.
Odpowiedzi:
Myślę, że najszybszym i najbardziej zwięzłym sposobem na zrobienie tego jest użycie wbudowanego indeksowania NumPy Fancy. Jeśli masz
ndarray
nazwęarr
, możesz zastąpić wszystkie elementy>255
wartościąx
w następujący sposób:Uruchomiłem to na mojej maszynie z losową matrycą 500 x 500, zastępując wszystkie wartości> 0,5 wartością 5, i zajęło to średnio 7,59 ms.
źródło
arr
, zamiast tworzyćresult
tablicę jak w OP.A
ale tworząc nową tablicę?np.array([1,2,3]
)Ponieważ tak naprawdę potrzebujesz innej tablicy, która jest
arr
tamarr < 255
, gdzie255
indziej, można to zrobić po prostu:Mówiąc bardziej ogólnie, dla dolnej i / lub górnej granicy:
Jeśli chcesz uzyskać dostęp do wartości powyżej 255 lub coś bardziej skomplikowanego, odpowiedź @ mtitan8 jest bardziej ogólna, ale
np.clip
inp.minimum
(lubnp.maximum
) jest ładniejsza i znacznie szybsza w twoim przypadku:Jeśli chcesz to zrobić w miejscu (tj. Zmodyfikować
arr
zamiast tworzyćresult
), możesz użyćout
parametrunp.minimum
:lub
(
out=
nazwa jest opcjonalna, ponieważ argumenty w tej samej kolejności, co definicja funkcji).W przypadku modyfikacji na miejscu indeksowanie logiczne znacznie przyspiesza (bez konieczności wykonywania, a następnie modyfikowania kopii osobno), ale nadal nie jest tak szybkie, jak
minimum
:Dla porównania, jeśli chcesz ograniczyć swoje wartości z minimum, jak i maksimum, bez
clip
konieczności robienia tego dwa razy, z czymś takim jaklub,
źródło
a[start:stop:step]
daje elementy tablicy odstart
dostop
, ale zamiast każdego elementu, zajmuje tylko każdystep
(jeśli zostanie pominięty,1
domyślnie jest ). Aby więc wyzerować wszystkiea[::2] = 0
Myślę, że możesz to zrobić najszybciej, używając
where
funkcji:Na przykład szukanie elementów większych niż 0,2 w tablicy numpy i zamiana tych na 0:
źródło
Możesz rozważyć użycie numpy.putmask :
Oto porównanie wydajności z wbudowanym indeksowaniem Numpy:
źródło
Innym sposobem jest użycie,
np.place
które zastępuje w miejscu i działa z tablicami wielowymiarowymi:źródło
np.place
był również wolniejszy w porównaniu do metody wbudowanej, chociaż w tym komentarzu twierdzi się coś przeciwnego.Możesz także użyć
&
,|
(i / lub) dla większej elastyczności:wartości od 5 do 10:
A[(A>5)&(A<10)]
wartości większe niż 10 lub mniejsze niż 5:
A[(A<5)|(A>10)]
źródło