Python - numpy 05 (연산, broadcasting)
지난 포스팅에서 numpy의 ndarray의 생성 방법과 원소를 가져오는 방법을 알아보았습니다. 이번에는 ndarray의 원소 간의 연산과 shape(모양)이 달라도 연산 할 수 있는 broadcasting에 대해 알아보겠습니다.
연산
ndarray의 원소 간의 연산은 기본적으로 요소별(element-wise) 연산입니다. 요소별 연산이란 같은 위치에 있는 원소끼리 연산을 하는 것을 말합니다.
import numpy as np
arr1 = np.arange(10)
arr2 = np.arange(10, 20)
print(arr1)
print(arr2)
print(arr1 + arr2)
print(arr1 - arr2)
print(arr1 * arr2)
print(arr1 / arr2)
arr1 + arr2
: arr1과 arr2의 같은 위치에 있는 원소끼리 더합니다.arr1 - arr2
: arr1과 arr2의 같은 위치에 있는 원소끼리 뺍니다.arr1 * arr2
: arr1과 arr2의 같은 위치에 있는 원소끼리 곱합니다.arr1 / arr2
: arr1과 arr2의 같은 위치에 있는 원소끼리 나눕니다.
[0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[10 12 14 16 18 20 22 24 26 28]
[-10 -10 -10 -10 -10 -10 -10 -10 -10 -10]
[ 0 11 24 39 56 75 96 119 144 171]
[0. 0.09090909 0.16666667 0.23076923 0.28571429 0.33333333 0.375 0.41176471 0.44444444 0.47368421]
함수를 이용한 연산
import numpy as np
arr1 = np.arange(10)
arr2 = np.arange(10, 20)
print(arr1)
print(arr2)
print(np.add(arr1, arr2))
print(np.subtract(arr1, arr2))
print(np.multiply(arr1, arr2))
print(np.divide(arr1, arr2))
np.add(arr1, arr2)
: arr1과 arr2의 같은 위치에 있는 원소끼리 더합니다.np.subtract(arr1, arr2)
: arr1과 arr2의 같은 위치에 있는 원소끼리 뺍니다.np.multiply(arr1, arr2)
: arr1과 arr2의 같은 위치에 있는 원소끼리 곱합니다.np.divide(arr1, arr2)
: arr1과 arr2의 같은 위치에 있는 원소끼리 나눕니다.
[0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[10 12 14 16 18 20 22 24 26 28]
[-10 -10 -10 -10 -10 -10 -10 -10 -10 -10]
[ 0 11 24 39 56 75 96 119 144 171]
[0. 0.09090909 0.16666667 0.23076923 0.28571429 0.33333333 0.375 0.41176471 0.44444444 0.47368421]
주의 할 점
연산을 할 때 shape(모양)이 같아야 합니다. shape이 다르면 에러가 발생합니다.
import numpy as np
arr1 = np.arange(10)
arr2 = np.arange(5)
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1과 arr2의 shape이 다르기 때문에 에러가 발생합니다.
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4]
Traceback (most recent call last):
File "main.py", line 8, in <module>
print(arr1 + arr2)
ValueError: operands could not be broadcast together with shapes (10,) (5,)
broadcasting(브로드캐스팅)
shape이 다른 배열끼리 연산을 할 때, shape을 맞춰주는 것을 브로드캐스팅이라고 합니다. 브로드캐스팅은 shape이 다른 배열끼리 연산을 할 때, shape을 맞춰주는 것을 말합니다. 다만 조건이 있습니다. 아래 그림을 보면서 브로드캐스팅이 가능한 조건을 알아보겠습니다.
참조: http://www.astroml.org/book_figures/appendix/fig_broadcast_visual.html
- 두 배열의 차원이 같거나, 한쪽이 1이어야 합니다.
- 두 배열의 차원이 같지 않다면, 차원이 1인 배열의 shape을 다른 배열의 shape에 맞춰줍니다.
- 두 배열의 shape이 같지 않다면, shape이 같지 않은 배열의 shape을 다른 배열의 shape에 맞춰줍니다.
- 두 배열의 shape이 같지 않고, 차원이 1이 아니라면 에러가 발생합니다.
무슨 말인지 어렵습니다. 그나마 그림이 낫네요. 예시를 그림을 보면서 알아보겠습니다.
(3, ) 과 상수
import numpy as np
arr1 = np.arange(3)
arr2 = 5
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1의 shape은 (3, )이고, arr2의 shape은 ()이기 때문에 브로드캐스팅이 가능합니다.
[0 1 2]
5
[5 6 7]
(3, 3) 과 (3, )
import numpy as np
arr1 = np.arange(9).reshape(3, 3)
arr2 = np.arange(3)
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1의 shape은 (3, 3)이고, arr2의 shape은 (3, )이기 때문에 브로드캐스팅이 가능합니다.
[[0 1 2]
[3 4 5]
[6 7 8]]
[0 1 2]
[[ 0 2 4]
[ 3 5 7]
[ 6 8 10]]
(3, 1) 과 (3, )
import numpy as np
arr1 = np.arange(3).reshape(3, 1)
arr2 = np.arange(3)
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1의 shape은 (3, 1)이고, arr2의 shape은 (3, )이기 때문에 브로드캐스팅이 가능합니다.
[[0]
[1]
[2]]
[0 1 2]
[[0 1 2]
[1 2 3]
[2 3 4]]
(3, 1) 과 (1, 3) - 실질적으로는 (3, ) 과 (3, ) 과 같습니다.
import numpy as np
arr1 = np.arange(3).reshape(3, 1)
arr2 = np.arange(3).reshape(1, 3)
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1의 shape은 (3, 1)이고, arr2의 shape은 (1, 3)이기 때문에 브로드캐스팅이 가능합니다.
[[0]
[1]
[2]]
[[0 1 2]]
[[0 1 2]
[1 2 3]
[2 3 4]]
(3, 1) 과 (3, 2) - 오류
import numpy as np
arr1 = np.arange(3).reshape(3, 1)
arr2 = np.arange(6).reshape(3, 2)
print(arr1)
print(arr2)
print(arr1 + arr2)
arr1 + arr2
: arr1의 shape은 (3, 1)이고, arr2의 shape은 (3, 2)이기 때문에 브로드캐스팅이 불가능합니다.
[[0]
[1]
[2]]
[[0 1]
[2 3]
[4 5]]
Traceback (most recent call last):
File "main.py", line 8, in <module>
print(arr1 + arr2)
ValueError: operands could not be broadcast together with shapes (3,1) (3,2)
해시태그: #python #numpy #연산 #broadcasting
댓글남기기