Python/Numpy

[Numpy] Numpy Vectorization & Broadcasting

데이터 세상 2021. 3. 5. 01:00
728x90
반응형

벡터화 (Vectorization)

  • 배열은 for 문을 작성하지 않고 데이터를 일괄 처리 가능
  • 같은 크기의 배열 간 산술 연산은 배열의 각 요소 단위로 적용
import numpy as np

arr = np.array([[1,2,3],[4,5,6]])
print(arr)
print(arr+arr)
print(arr-arr)
print(arr*arr)
print(arr/arr)
print(arr ** arr)

>>
[[1 2 3]
 [4 5 6]]
[[ 2  4  6]
 [ 8 10 12]]
[[0 0 0]
 [0 0 0]]
[[ 1  4  9]
 [16 25 36]]
[[1. 1. 1.]
 [1. 1. 1.]]
[[    1     4    27]
 [  256  3125 46656]]

 

브로드캐스팅(BroadCasting)

  • 스칼라 인자: 모든 요소에 각각 적용
  • 다른 shape의 배열 간의 산술 연산 수행
  • 연산을 수행하는 축을 제외한 나머지 축의 shape이 일치하거나 둘 중 하나의 길이가 1이여야 함

import numpy as np

arr = np.array([[1,2,3],[4,5,6]])
print(arr+10)
print(arr*3)

>>
[[11 12 13]
 [14 15 16]]
[[ 3  6  9]
 [12 15 18]]

 

indexing & slicing

  • 인덱싱[i], 슬라이싱[i:j], 불리언 인덱싱

Slicing

  • 배열명[시작인덱스:마지막인덱스:간격]
import numpy as np
arr = np.array([11, 22, 33, 44, 55, 66])
print(arr[0:6:1])
print(arr[0:6]) # 간격의 기본 값은 1
print(arr[0:])  # 마지막 인덱스의 기본값은 '마지막인덱스+1'
print(arr[:])   # 시작 인덱스의 기본값은 0
>> [11 22 33 44 55 66]

# 슬라이싱 시 음수 사용 가능
print(arr[-6::2])
>> [11 33 55]
print(arr[5:2:-1])
>> [66 55 44]
print(arr[2:-1])
>> [33 44 55]

# 배열 전체에 대하여 간격을 음수로 사용하면 역순으로 선택
print(arr[::-1])
>> [66 55 44 33 22 11]

View

  • numpy의 슬라이싱은 원본데이터의 뷰를 제공
  • 데이터를 새롭게 복사해 오는 것이 아니라 기존의 데이터와 연결(얕은 복사)
    • 데이터를 변경할 경우 원본에 반영
    • 성능을 높이고 메모리 이슈를 피하기 위해 얕은 복사를 함
  • vs. 리스트의 슬라이싱은 데이터 깊은 복사, 슬라이싱 데이터 변경 시 원본 데이터 변경 없음
  • numpy의 원본 데이터를 훼손하지 않으면서 indexing 또는 slicing을 활용하기 위해서는 깊은 복사 후 절차 진행
    • arr.copy()
import numpy as np

arr1 = np.array([0,-1,-1,1,100,100,100,6,7])
print(arr1)

# deep copy
arr2 = arr1.copy()
print(arr2)

# slicing
arr_part = arr2[1:5]
arr_part[0:2] = 0 ## 원본데이터가 변경됨
print(arr_part)
print(arr2)
print(arr1)

>>
[  0  -1  -1   1 100 100 100   6   7]
[  0  -1  -1   1 100 100 100   6   7]
[  0   0   1 100]
[  0   0   0   1 100 100 100   6   7]
[  0  -1  -1   1 100 100 100   6   7]

다차원 배열 인덱싱

  • 재귀적 접근
  • 콤마를 이용한 인덱싱
arr = np.arange(20).reshape(4, -1)
>>
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])

arr[0]
>> array([0, 1, 2, 3, 4])

arr[1][2]
>> 7
arr[1, 2]
>> 7

다차원 배열의 슬라이싱

  • 재귀적 접근
  • 콤마를 이용한 인덱싱
arr = np.arange(30).reshape(2, 3, -1)
>>
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14]],

       [[15, 16, 17, 18, 19],
        [20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29]]])

arr[1, 0, 2]
>> 17

arr[:1, :, :3]
>>
array([[[ 0,  1,  2],
        [ 5,  6,  7],
        [10, 11, 12]]])

boolean indexing

  • 불리언 배열: 불리언 값으로 이루어진 배열
  • 불리언 인덱싱: True에 해당하는 위치에 있는 값만 반환
  • 불리언 인덱싱 후 해당 값을 다시 인덱싱/슬라이싱으로 활용 가능
import numpy as np

arr = np.array([10, 20, 30, 40, 50, 60], int)
print(arr)
print(arr % 3 == 0)
print(arr[arr%3==0])

>>
[10 20 30 40 50 60]
[False False True False False True]
[30 60]

fancy indexing

  • 정수가 담긴 ndarray나 리스트로 특정 위치에 있는 값을 가져올 수 있음
  • 인덱스 값이 주어진 순서대로 가져오게 됨
  • 순서에 따라 일종의 좌표처럼 인덱싱 수행
  • 다수의 인덱스를 사용하여 원소를 조회
import numpy as np

arr = np.arange(10,20)
print(arr)
print(arr[[0,2,4,6]])
print(arr[[3,0,1]])

arr2 = np.arange(20).reshape(4,5)
print(arr2)
print(arr2[[0,1],[4]])

>>
[10 11 12 13 14 15 16 17 18 19]
[10 12 14 16]
[13 10 11]
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
[4 9]
728x90
반응형

'Python > Numpy' 카테고리의 다른 글

[Numpy] Numpy Functions  (1) 2021.03.05
[Numpy] Numpy Shape Manipulation  (0) 2021.03.05
[Numpy] Numpy (Numerical Python)  (0) 2021.02.24