[OpenCV] Numpy (2)

rlath·2022년 4월 23일
0

OpenCV

목록 보기
17/17

인덱싱과 슬라이싱

NumPy 배열은 파이썬의 리스트처럼 인덱스로 각 요소에 접근할 수 있다. 당연히 배열의 차원에 따라서 인덱스의 개수도 달라진다.

인덱싱

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[5]
5
>>> b = np.arange(12).reshape(3, 4)
>>> b
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [8, 9, 10 ,11]])
>>> b[1]
array([4, 5, 6, 7])
>>> b[1, 2]
6

슬라이싱

파이썬 리스트처럼 복제본을 얻고 싶다면 ndarray.copy() 함수를 호출해야 한다.

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[2:5]
array([2, 3, 4])
>>> a[5:]
array([5, 6, 7, 8, 9])
>>> a[:]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = np.arange(12).reshape(3, 4)
>>> b
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [8, 9, 10, 11]])
>>> b[0:2, 1]
array([1, 5])
>>> b[0:2, 1:3]
array([1, 2],
      [5, 6]])
>>> b[2, :]
array([8, 9, 10 ,11])
>>> b[:, 1]
array([1, 5, 9])
>>> b[0:2, 1:3] = 0
>>> b
array([[0, 0, 0, 3],
       [4, 0, 0, 7],
       [8, 9, 10, 11]])

팬시 인덱싱

배여 인덱스에 다른 배열을 전달해서 원하는 요소를 선택하는 방법을 말한다. 전달하는 배열에 숫자를 포함하고 있으면 해당 인덱스에 맞게 선택되고, 배열에 bool 값을 포함하면 True인 값을 갖는 요소만 선택된다.

>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a[[1, 3]]
array([1, 3])
>>> a[[True, False, True, False, True]]
array([0, 2, 4])

NumPy 배열에 비교 연산을 하면 개별 요소들이 조건을 만족하는지 알 수 있다. bool 값을 갖는 배열을 배열의 인덱스 대신 사용하면 True 값 위치의 값들만 얻을 수 있는데, 이 둘을 한번에 실행하면 원하는 조건의 값만 얻을 수 있다.

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = a > 5
>>> b
array([False, False, False, False, False, False, True, True, True, True])
>>> a[b]
array([6, 7, 8, 9])
>>> a[a>5]
array([6, 7, 8, 9])
>>> a[a>5] = 1
>>> a
array([0, 1, 2, 3, 4, 5, 1, 1, 1, 1])

병합과 분리

병합

2개 이상의 NumPy 배열을 병합하는 방법은 크게 두 가지가 있다. 단순히 배열들을 이어 붙여서 크기를 키우는 방법과 새로운 차원을 만들어 서로서로 끼워넣는 방법이다.

NumPy 배열의 shape 속성을 확인하면 튜플 형식으로 몇개의 숫자가 나오는 것을 이미 알고 있다. 각 숫자의 개수는 차원을 의미하고, 맨 앞부터 0, 1, 2, ... 순으로 축 번호를 사용한다. 예를 들어 어느 배열의 shape가 (10, 20, 3) 이면 3개의 축이 있고 10은 0번 축, 20은 1번 축, 3은 2번 축을 나타낸다. 축을 기준으로 작업을 한다는 뜻은 바로 shape의 각 순서에 따라 작업을 한다는 것이다.

  • numpy.hstack(arrays) : arrays 배열을 수평으로 병합
  • numpy.vstack(arrays) : arrays 배열을 수직으로 병합
  • numpy.concatenate(arrays, axis=0) : arrays 배열을 지정한 축 기준으로 병합
    • arrays : 병합 대상 배열(튜플)
    • axis : 작업할 대상 축 번호(지정하지 않으면 0번을 의미하고, -1은 마지막 축 번호를 의미)
>>> a = np.arange(4).reshape(2, 2)
>>> a
array([[0, 1],
       [2, 3]])
>>> b = np.arange(10, 14).reshape(2, 2)
>>> b
array([[10, 11],
       [12, 13]])
>>> np.vstack((a, b))
array([[0, 1],
       [2, 3],
       [10, 11],
       [12, 13]])
>>> np.hstack((a, b))
array([[0, 1, 10, 11],
       [2, 3, 12, 13]])
>>> np.concatenate((a, b), 0)
array([[0, 1, 10, 11],
       [2, 3, 12, 13]])

분리

  • numpy.vsplit(array, indice) : array 배열을 수평으로 분리
  • numpy.hsplit(array, indice) : array 배열을 수직으로 분리
  • numpy.split(array, indice, axis=0) : array 배열을 axis 축으로 분리
    • array : 분리할 배열
    • indice : 분리할 개수 또는 인덱스 (정수 또는 1차원 배열)
    • axis : 기준 축 번호
>>> a = np.arange(12)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> np.hsplit(a, 3)
[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array(8, 9, 10, 11])]
>>> np.hsplit(a, [3, 6])
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([9, 10, 11])]
>>> np.split(a, 3, 0)
[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array(8, 9, 10, 11])]
>>> np.split(a, [3, 6, 9], 0)
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([9, 10, 11])]
>>> b = np.arange(12).reshape(4, 3)
>>> b
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8],
       [9, 10, 11]])
>>> np.vsplit(b, 2)
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([9, 10, 11])
>>> np.split(b, 2, 0)
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([9, 10, 11])
>>> np.hsplit(b, [1])
[array([0], [3], [6], [9]), array([1, 2], [4, 5], [7, 8], [10, 11])] 

검색

NumPy 배열을 사용하는 이유는 수많은 데이터를 쉽고 빠르게 다루기 때문이고, 이미지 작업도 마찬가지다. 그래서 NumPy를 쓰다 보면 배열 안에서 관심 있는 데이터만을 찾거나 찾아서 바꾸는 일이 필요하다.

  • ret = numpy.where(condition, [t, f]) : 조건에 맞는 요소를 찾기
    • ret : 검색 조건에 맞는 요소의 인덱스 또는 변경된 값으로 채워진 배열(튜플)
    • condition : 검색에 사용할 조건식
    • t, f : 조건에 따라 지정할 값 또는 배열, 배열의 경우 조건에 사용한 배열과 같은 shape
      • t : 조건에 맞는 값에 지정할 값이나 배열
        • f : 조건에 틀린 값에 지정할 값이나 배열

  • numpy.nonzero(array) : array에서 요소 중에 0이 아닌 요소의 인덱스들을 반환(튜플)
  • numpy.all(array, [axis]) : array의 모든 요소가 True인지 검색
    • array : 검색 대상 배열
    • axis : 검색할 기준 축, 생략하면 모든 요소 검색, 지정하면 축 개수별로 결과 반환
  • numpy.any(array, [axis]) : array의 어느 요소이든 True가 있는지 검색
>>> a = np.arange(10, 20)
>>> a
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> np.where(a > 15)
(array([6, 7, 8, 9],)
>>> np.where(a > 15, 1, 0)
array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1])

>>> a
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> np.where(a > 15, 99, a)
array([10, 11, 12, 13, 14, 15, 99, 99, 99, 99])
>>> np. where(a > 15, a, 0)
array([0, 0, 0, 0, 0, 0, 16, 17, 18, 19])

>>> b = np.arange(12).reshape(3, 4)
>>> b
array([0, 1, 2, 3],
      [4, 5, 6, 7], 
      [8, 9, 10, 11])
>>> coords = np.where(b > 6)
>>> coords
(array([1, 2, 2, 2, 2]), array([3, 0, 1, 2, 3]))
>>> np.stack((coords[0], coords[1]), -1)
array([[1, 3], 
       [2, 0],
       [2, 1],
       [2, 2],
       [2, 3]])

profile
백엔드 개발자

0개의 댓글