2D NumPy 배열을 가지고 있으며 임계 값 T 이상인 255.0의 모든 값을 바꾸고 싶습니다. 내 지식으로는 가장 기본적인 방법은 다음과 같습니다.
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
-
가장 간결하고 파이썬적인 방법은 무엇입니까?
-
이 작업을 수행하는 더 빠른 방법 (간결하고 덜 간결한 방법)이 있습니까?
이것은 사람 머리의 MRI 스캔을위한 창 / 레벨 조정 서브 루틴의 일부입니다. 2D numpy 배열은 이미지 픽셀 데이터입니다.
답변
가장 빠르고 간결한 방법은 NumPy의 내장 Fancy 색인 생성을 사용하는 것입니다. ndarray
named 가 있으면 다음과 같이 arr
모든 요소 >255
를 값 x
으로 바꿀 수 있습니다 .
arr[arr > 255] = x
내 컴퓨터에서 500 x 임의의 매트릭스로 0.5을 5로 바꾸고 평균 7.59ms가 걸렸습니다.
In [1]: import numpy as np
In [2]: A = np.random.rand(500, 500)
In [3]: timeit A[A > 0.5] = 5
100 loops, best of 3: 7.59 ms per loop
답변
당신은 실제로 다른 배열을 원하기 때문에 , 그리고 그렇지 않으면,이 간단하게 할 수 있습니다 :arr
arr < 255
255
result = np.minimum(arr, 255)
보다 일반적으로, 하한 및 / 또는 상한의 경우 :
result = np.clip(arr, 0, 255)
그냥 더 복잡 255 값, 또는 무언가에 액세스하려면, @ mtitan8의 대답은 더 일반적이지만, np.clip
및 np.minimum
(또는 np.maximum
) 좋네요 훨씬 빨리 케이스 :
In [292]: timeit np.minimum(a, 255)
100000 loops, best of 3: 19.6 µs per loop
In [293]: %%timeit
.....: c = np.copy(a)
.....: c[a>255] = 255
.....:
10000 loops, best of 3: 86.6 µs per loop
제자리에서 수행하려면 (즉, arr
대신에 수정 result
) out
매개 변수를 사용할 수 있습니다 np.minimum
.
np.minimum(arr, 255, out=arr)
또는
np.clip(arr, 0, 255, arr)
( out=
함수는 함수 정의와 동일한 순서로 인수되므로 선택 사항입니다.)
전체 수정의 경우 부울 색인 생성 속도가 빨라지지만 (복사본을 별도로 만든 다음 수정하지 않아도 됨) 여전히 다음과 같이 빠르지는 않습니다 minimum
.
In [328]: %%timeit
.....: a = np.random.randint(0, 300, (100,100))
.....: np.minimum(a, 255, a)
.....:
100000 loops, best of 3: 303 µs per loop
In [329]: %%timeit
.....: a = np.random.randint(0, 300, (100,100))
.....: a[a>255] = 255
.....:
100000 loops, best of 3: 356 µs per loop
비교를 위해 최소값과 최대 값으로 값을 제한 clip
하려면 다음과 같이 두 번 수행하지 않아도됩니다.
np.minimum(a, 255, a)
np.maximum(a, 0, a)
또는,
a[a>255] = 255
a[a<0] = 0
답변
나는 당신이 where
기능 을 사용하여 이것을 가장 빨리 달성 할 수 있다고 생각합니다 :
예를 들어 numpy 배열에서 0.2보다 큰 항목을 찾고 0으로 대체하면 다음과 같습니다.
import numpy as np
nums = np.random.rand(4,3)
print np.where(nums > 0.2, 0, nums)
답변
numpy.putmask 사용을 고려할 수 있습니다 .
np.putmask(arr, arr>=T, 255.0)
Numpy의 내장 인덱싱과의 성능 비교는 다음과 같습니다.
In [1]: import numpy as np
In [2]: A = np.random.rand(500, 500)
In [3]: timeit np.putmask(A, A>0.5, 5)
1000 loops, best of 3: 1.34 ms per loop
In [4]: timeit A[A > 0.5] = 5
1000 loops, best of 3: 1.82 ms per loop
답변
다른 방법은 np.place
전체 교체를 수행하고 다차원 배열과 함께 작동하는 것입니다.
import numpy as np
# create 2x3 array with numbers 0..5
arr = np.arange(6).reshape(2, 3)
# replace 0 with -10
np.place(arr, arr == 0, -10)
답변
유연성을 높이기 위해 &
, |
및 / 또는을 사용할 수도 있습니다 .
5와 10 사이의 값 : A[(A>5)&(A<10)]
10보다 크거나 5보다 작은 값 : A[(A<5)|(A>10)]