앞서 이용한 다차원 인덱싱을 응용하여 boolean 인덱싱을 할 수 있다.

주로 mask라고 얘기하는데, boolean 인덱싱을 통해 만들어낸 배열을 통해 원하는 행 또는 열의 값만 뽑아낼 수 있다.

즉, mask처럼 가리고 싶은 부분은 가리고 원하는 요소는 꺼낼 수 있다.

 

예를 살펴보자.

 

names=np.array(['kwan','lee','kyunh','koo','bae','yu','hyeong','ho','min','song','jin'])
names

array(['kwan', 'lee', 'kyunh', 'koo', 'bae', 'yu', 'hyeong', 'ho', 'min',
       'song', 'jin'], dtype='<U6')

names.shape
(11,)

문자열 배열을 생성하고,

ran_num=np.random.randn(11,4)
ran_num

array([[-0.59103603,  0.82348054, -0.29187746, -0.22239091],
       [-0.8100299 ,  0.84844129, -0.89056272, -0.56269183],
       [ 1.03756042, -1.27040716, -0.14321331, -1.29123492],
       [ 0.39628204, -1.18455294, -1.11007655, -0.25026466],
       [ 0.74178116, -1.39881718,  1.45385185,  1.7651273 ],
       [ 0.5388867 , -1.33991598,  0.82725191, -0.95091188],
       [ 1.77272678,  0.95240797, -0.94997094, -1.02506259],
       [-2.10105478, -0.47656731, -0.86786481, -1.54414126],
       [ 1.18391322, -0.82079135,  1.5303018 , -1.20934383],
       [-2.05976446, -2.59316339, -0.65387812,  0.52717579],
       [-0.48744984,  0.66963489,  0.69548501, -0.9389433 ]])
       
ran_num.shape

(11, 4)

숫자형 이차원 배열을 생성해준다.

np.random.randn() 함수는 기대값이 0, 표준편차가 1인 정규 분포를 따르는 난수 생성 함수이다.

np.random.rand() 함수는 0~1의 난수를 생성해주는 함수이다.

 

이제, names배열의 각 요소가 ran_num의 각 행과 연결된다고 가정해보자. 그렇기에 행을 맞춰 난수를 생성한 것이다.

이때, names가 'kwan'인 행의 요소들만 보고 싶을때 마스크를 사용한다.

 

names_kwan_mask=(names=='kwan')
names_kwan_mask

array([ True, False, False, False, False, False, False, False, False,
       False, False])

위는 요소가 'kwan'인 항목에 대한 mask를 생성한 것이다.

 

ran_num[names_kwan_mask,:]

array([[-0.59103603,  0.82348054, -0.29187746, -0.22239091]])

위 결과를 보면 'kwan'인 요소를 꺼내온다.

이를 위해 요소가 'kwan'인 것에 대한 boolean 값을 가지는 mask를 만들었고 마스크를 인덱싱에 응용하여 'ran_num'의 0행을 꺼냇다.

ran_num[names=='koo',:]

array([[ 0.39628204, -1.18455294, -1.11007655, -0.25026466]])

위는 요소가 'koo'인 행의 데이터만 꺼내온다.

ran_num[(names=='koo')|(names=='kwan'),:]

array([[-0.59103603,  0.82348054, -0.29187746, -0.22239091],
       [ 0.39628204, -1.18455294, -1.11007655, -0.25026466]])

위는 'names'의 요소가 'koo' or(|) 'kwan'인 행의 데이터만 꺼내온다.

 

물론 ran_num 배열 자체적으로도 마스크를 만들고, 이를 응용한 인덱싱이 가능하다. 

ran_num 배열에서 0번째 열의 값이 0보다 작은 행을 구해보자.

 

먼저 마스크를 만들어보자.

ran_num[:,0]<0

array([ True,  True, False, False, False, False, False,  True, False,
        True,  True])

위에서 만든 마스크를 이용해 0번째 열의 값이 0보다 작은 행을 구해보자.

ran_num[ran_num[:,0]<0,2:4]

array([[-0.29187746, -0.22239091],
       [-0.89056272, -0.56269183],
       [-0.86786481, -1.54414126],
       [-0.65387812,  0.52717579],
       [ 0.69548501, -0.9389433 ]])

다른 예로 0번째 열의 값이 0보다 작은 행의 2,3번째 열 값을 구해보자.

 

ran_num[ran_num[:,0]<0,2:4]=0
ran_num

array([[-0.59103603,  0.82348054,  0.        ,  0.        ],
       [-0.8100299 ,  0.84844129,  0.        ,  0.        ],
       [ 1.03756042, -1.27040716, -0.14321331, -1.29123492],
       [ 0.39628204, -1.18455294, -1.11007655, -0.25026466],
       [ 0.74178116, -1.39881718,  1.45385185,  1.7651273 ],
       [ 0.5388867 , -1.33991598,  0.82725191, -0.95091188],
       [ 1.77272678,  0.95240797, -0.94997094, -1.02506259],
       [-2.10105478, -0.47656731,  0.        ,  0.        ],
       [ 1.18391322, -0.82079135,  1.5303018 , -1.20934383],
       [-2.05976446, -2.59316339,  0.        ,  0.        ],
       [-0.48744984,  0.66963489,  0.        ,  0.        ]])

 

ML,DL에서도 masking이라는 개념이 있고, 위 boolean masking을 다시한번 공부하며 느낀 것이지만 아직도 쓰임이 어디에 잘 쓰이는지를 깨닫지는 못했다....;;

'Data analysis > Numpy' 카테고리의 다른 글

6. Numpy 함수  (0) 2021.03.19
4. Array 인덱싱  (0) 2021.03.19
3. Array 연산  (0) 2021.03.19
2. zeros(),ones(),arange() 함수  (0) 2021.03.19
1.Numpy란?  (0) 2021.03.19

+ Recent posts