조건이 충족되면 Numpy 요소 교체


94

조건이 충족되면 각 요소가 1 또는 0으로 변경되도록 조작해야하는 큰 numpy 배열이 있습니다 (나중에 픽셀 마스크로 사용됨). 배열에는 약 8 백만 개의 요소가 있으며 현재 방법은 축소 파이프 라인에 너무 오래 걸립니다.

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

속도를 높일 수있는 numpy 함수가 있습니까?


1
당신은 어떤 일이 일어나기를 mask_data[y,x]==3원합니까?
DSM

좋은 점은 여전히 ​​잘못된 픽셀입니다. 조건을 변경하겠습니다if mask_data[y,x]>=3:
ChrisFro 2013

답변:


128
>>> 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]])

다음과 같이 단축 할 수 있습니다.

>>> c = (a < 3).astype(int)

2
일부 열을 분할 한 다음 다시 할당하지 않고 특정 열에서이를 발생시키는 방법은 무엇입니까? 예를 들어, [2, 3] 열의 요소 만 조건이 충족되면 값을 변경해야하며 다른 열은 조건이 충족되는지 여부에 관계없이 변경되지 않습니다.
kuixiong 19

사실이지만 0과 1의 경우에만 해당됩니다. 아래에서보다 일반적인 답변을 참조하십시오 (효율성 비용)
borgr

89
>>> 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]])
>>>

예를 들어, 부울 배열로 인덱싱을 참조하십시오 .


3
감사합니다! 변경 한 값을 참조하려면 a[a > 3] = -101+a[a > 3].
pexmar

1
@pexmar a[a > 3] = -101+a[a > 3]대신 그렇게 a[a > 3] += -101하면 메모리 누수가 발생할 가능성이 큽니다.
Samuel Prevost

1
pexmar가 요청한대로 변경 한 값을 어떻게 참조합니까 ??
Juan

34

빠른 (가장 유연한) 방법을 사용하는 것이다 np.where 두 배열 중에서 선택 마스크 (참과 거짓 값의 배열)에있어서, 이는 :

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)

다음을 생성합니다.

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]]

1
조건이 충족되지 않은 경우 아무것도 교체하지 않으려는 경우 가장 좋은 방법은 무엇입니까? ie 원래 번호를 그대로 두지 않으면 조건이 충족 될 때만 제공 값으로 교체합니다 ....
Abhishek Sengupta

1
a의 모든 값 (3보다 작은 값)을 바꾸고 나머지는 그대로 유지하려면 다음을 사용하십시오.a[a<3] = 0
Markus Dutschke

3

다음과 같이 한 단계로 마스크 배열을 만들 수 있습니다.

mask_data = input_mask_data < 3

그러면 픽셀 마스크로 사용할 수있는 부울 배열이 생성됩니다. 코드 에서처럼 입력 배열을 변경하지 않았지만 마스크 데이터를 저장할 새 배열을 만들었습니다.이 방법을 사용하는 것이 좋습니다.

>>> 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)
>>> 

1
네. 영업 이익이 정말로 0과 1을 원한다면, 그는 사용할 수 있습니다 .astype(int)또는 *1, 그러나의 배열 True과는 False그대로 단지 좋은 같습니다.
DSM

-4

질문을 이해했는지 잘 모르겠지만 다음과 같이 작성하면 :

mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0

이렇게하면 x 및 y 인덱스가 3보다 작은 마스크 데이터의 모든 값이 1이되고 나머지는 모두 0이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.