이번 포스팅에서는 넘파이 배열의 연산 방식에 대해 알아보도록 하겠습니다.
Element-wise 연산?
arr1 = np.random.randint(-5, 5, (5, ))
print(arr1) # [ 1 -1 -3 3 2]
arr2 = np.random.randint(-5, 5, (5, ))
print(arr2) # [ 3 4 -5 4 -3]
print(arr1 + arr2)
# [ 4 3 -8 7 -1]
기본적으로 넘파이 배열은 모두 원소별 연산을 수행합니다.
원소별로 연산한다는 것의 의미는 각 배열의 동일한 인덱스에 위치한 값들끼리 계산한다는 말입니다.
단, 연산하는 배열들의 shape은 동일해야 합니다.
M = np.random.randint(1, 5, (2, 3))
print(M)
# [[2 4 1]
# [4 4 2]]
N = np.random.randint(1, 5, (2, 3))
print(N)
# [[1 3 4]
# [1 2 4]]
print(M + N)
# [[3 7 5]
# [5 6 6]]
print(M - N)
# [[ 1 1 -3]
# [ 3 2 -2]]
print(M >= N)
# [[ True True False]
# [ True True False]]
2차원 배열의 원소별 연산 예제입니다.
- 산술 연산자
a = np.random.randint(1, 5, (5, ))
print(a)
# [4 3 2 1 4]
b = np.random.randint(1, 5, (5, ))
print(b)
# [3 1 4 1 4]
print('a + b = {}'.format(a + b))
# a + b = [7 4 6 2 8]
print('a - b = {}'.format(a - b))
# a - b = [ 1 2 -2 0 0]
print('a * b = {}'.format(a * b))
# a * b = [12 3 8 1 16]
print('a / b = {}'.format(a / b))
# a / b = [1.33333333 3. 0.5 1. 1.]
print('a % b = {}'.format(a % b))
# a % b = [1 0 2 0 0]
print('a // b = {}'.format(a // b))
# a // b = [1 3 0 1 1]
print('a ** b = {}'.format(a ** b))
# a ** b = [64 3 16 1 256]
넘파이 배열은 사칙연산 뿐만 아니라 몫, 나머지, 지수 연산도 수행 가능합니다.
- 비교 연산자
a = np.random.randint(-5, 5, (5, ))
print(a) # [-5 -1 0 -1 4]
b = np.random.randint(-5, 5, (5, ))
print(b) # [ 3 -4 2 1 -5]
print('a > b: {}'.format(a > b))
# a > b: [False True False False True]
print('a >= b: {}'.format(a > b))
# a >= b: [False True False False True]
print('a < b: {}'.format(a < b))
# a < b: [ True False True True False]
print('a <= b: {}'.format(a <= b))
# a <= b: [ True False True True False]
print('a == b: {}'.format(a == b))
# a == b: [False False False False False]
print('a != b: {}'.format(a != b))
# a != b: [ True True True True True]
비교 연산자를 사용해서 넘파이 배열에 대한 연산을 수행하는 경우에는 불리언 배열을 리턴합니다.
리턴 받은 불리언 배열을 사용해서 배열을 마스킹할 수 있습니다.
- 마스킹
arr = np.arange(5)
print(arr)
# [0 1 2 3 4]
mask = np.array([0, 1, 0, 1, 0])
print(arr * mask)
# [0 1 0 3 0]
마스킹은 필터링(filtering)을 의미합니다.
0, 1로 구성된 배열을 사용해서 배열의 특정 부분만 남기고 나머지 부분은 모두 0으로 처리합니다.
matrix = np.arange(1, 5).reshape((2, 2))
print(matrix)
# [[1 2]
# [3 4]]
mask = np.array([[0, 0], [1, 0]])
print(matrix * mask)
# [[0 0]
# [3 0]]
2차원 배열에 대해 마스킹 연산을 수행하는 예제입니다.
마치며
이상으로 넘파이 배열의 원소별 연산에 대한 정리를 마치도록 하겠습니다.
원소별 연산 방식(Element-wise operation)은 브로드캐스팅 개념을 이해하기 위한 필수 개념입니다.
다음 포스팅에서는 대망의 브로드캐스팅에 대해 알아보도록 하겠습니다.
'파이썬・ML > numpy' 카테고리의 다른 글
넘파이 브로드캐스팅(broadcasting) 이해하기 (0) | 2023.07.27 |
---|---|
넘파이 배열의 형태 조작하기(reshape/resize) (0) | 2023.07.27 |
넘파이 배열의 생성법과 기본 속성 이해하기 (0) | 2023.07.27 |
넘파이 배열 shape 속성에 대한 이해 (0) | 2023.07.27 |
넘파이 np.repeat(), np.tile() 배열 반복하기 (0) | 2023.06.16 |