※ 관련포스팅
1편 : 2021.06.29 - [코딩/Python] - [Python/파이썬] Numpy 기초 1편 : Array 생성 및 인덱싱,슬라이싱
2편 : 2021.06.30 - [코딩/Python] - [Python/파이썬] Numpy 기초 2편 : numpy의 여러가지 연산
이번 편에서는 numpy의 각종 연산에 대한 부분을 알아본다. numpy의 행렬 계산은 우리가 일반적으로 알고 있는 선형대수 행렬 계산 외에 브로드캐스팅이라는 개념이 존재한다. 참고링크의 예시들을 따라하며 공부해 본 내용을 정리해보았다.
1. 행렬 크기가 서로 같은 경우의 연산
아래와 같이 2*2의 2차원 행렬 2개(t1, t2)를 정의해보았다. 행렬 크기가 같은 경우 어떻게 계산이 이루어지는지 아래 여러가지 예시를 통해 공부하였다.
<코드>
# Case1. 크기가 같은 경우의 연산
t1 = np.array([[1,2],[3,4]]) #2*2 행렬 선언 t1
t2 = np.array([[1,2],[3,4]]) #2*2 행렬 선언 t2
<결과>
#t1
array([[1, 2],
[3, 4]])
#t2
array([[1, 2],
[3, 4]])
1) 행렬 덧셈
<코드>
t1+t2 #행렬 덧셈
<결과>
array([[2, 4],
[6, 8]])
2) 행렬 뺄셈
<코드>
t1-t2 #행렬 뺄셈
<결과>
array([[0, 0],
[0, 0]])
3) 행렬 곱셈(element-wise 곱셈) : 요소별 곱셈
numpy의 행렬 곱셈은 일반적으로 알고있는 선형대수의 행렬 곱이 아니다. element-wise 라고 하며, 같은 위치 요소의 곱으로 이루어진다. 아래 결과를 확인해보자.
<코드>
#numpy 행렬의 곱셈은 행렬 곱이 아닌 같은 위치 요소의 곱으로 이루어진다.(element-wise 곱셈)
t1*t2
<결과>
array([[ 1, 4],
[ 9, 16]])
4) 나눗셈
나눗셈은 곱셈과 마찬가지로 element-wise로 계산되므로 추가 설명을 생략한다.
<코드>
t1/t2 #나눗셈도 마찬가지로 element-wise
<결과>
array([[1., 1.],
[1., 1.]])
5) 행렬 곱셈(dot) : 선형대수학 행렬 곱셈
우리가 선형대수학에서 배우는 행렬 곱셈은 dot 함수를 통해 구할 수 있다.
<코드>
#행렬곱은 dot 함수에 의해 구해진다.
t1.dot(t2)
<결과>
array([[ 7, 10],
[15, 22]])
2. 브로드캐스팅(Broadcasting)
numpy 행렬 연산에서는 브로드캐스팅(Broadcasting)이라는 개념이 있다. 선형대수학에서의 행렬 합, 차이를 구할 때는 두 행렬의 크기가 같아야 한다. numpy에서는 두 행렬의 크기가 달라도 자동으로 크기가 큰 행렬 기준으로 확장하여 계산하여 준다. 아래 예시를 통해 알아보자.
<코드>
#브로드캐스팅 연산을 위한 행렬 정의
t3 = np.array([[1,2,3]]) #(1,3) : 2차원
t4 = np.array([3]) #(1,) : 1차원
1) 크기가 다른 행렬 합계
위와 같이 크기와 차원이 달라도 numpy 행렬의 합계는 자동으로 브로드캐스팅이 적용되어 t4의 행렬이 아래와 같이 변경되어 계산된다.
#t4 의 확장
[3] -> [3] [3] [3]
<코드>
# 브로드캐스팅 합계 t4 : (1,) -> 동일한 요소의 (1,3)으로 변경하여 계산
# 원래 행렬의 연산은 크기가 같은 행렬에 대해서만 계산이 가능하지만 numpy는 브로드캐스팅이 있다.
t3+t4
<결과>
array([[4, 5, 6]]) #(3,1) : 2차원
따라서 위 결과처럼 t3 행렬에 각각 [3]이 더해져 2차원 행렬인 [[4,5,6]]이 출력된다.
2) 크기가 다른 행렬 곱셈
곱셈을 설명하기 위해 새로운 행렬 t5, t6을 선언해보았다.
<코드>
t5 = np.array([[1,2,3],[4,5,6]])
t6 = np.array([[1],[2]])
<t5, t6 출력>
#t5 : (3,2) 2차원 행렬
array([[1, 2, 3],
[4, 5, 6]])
#t6 : (2,1) 2차원 행렬
array([[1],
[2]])
위에서 언급했던대로 크기가 같은 행렬이라면 element-wise로 각각 요소의 곱으로 계산되지만, 크기가 다른 곱셈 적용시 브로드캐스팅이 적용된다.
<코드>
# numpy의 행렬곱셈은 같은 요소의 곱으로 이루어지나 위처럼 크기가 다른경우 자동으로 브로드캐스팅되어 계산 됨.
t5 * t6
<결과>
array([[ 1, 2, 3],
[ 8, 10, 12]])
3. 그 밖의 함수 연산
1) 최대값, 최소값
numpy의 행렬 요소 중 최대값, 최소값을 구하려면 max( ), min( ) 함수를 사용하자. 차원, 크기와 상관없이 최대값, 최소값을 출력한다. numpy array는 위 의 t5를 활용한다.
#t5
array([[1, 2, 3],
[4, 5, 6]])
<코드>
print("최대값 : ", t5.max())
print("최소값 : ", t5.min())
<결과>
최대값 : 6
최소값 : 1
차원 연산이 필요한 경우 axis라는 파라미터를 통해 차원별 연산을 수행할 수 있다. 위 처럼 아무 것도 지정안한 경우 axis=0이 디폴트값이라고 생각하면 된다.
axis = 0 : 열 연산 axis = 1 : 행 연산 axis = 2 : 3차원 연산 |
아래 그림은 axis를 이해하기 위한 이미지이다. 참고!
위 t5 행렬에 최대값, 최소값을 axis에 따라 어떻게 계산되는지 확인해보면 아래 결과처럼 axis=0일 경우에 행별 계산으로 인한 1차원 벡터, axis=1일 경우에 열별 계산으로 인한 1차원 벡터를 구할 수 있다.
<코드>
#행연산 최대값(결과는 행의 각 요소를 비교한 1차원 벡터임)
print("행연산 최대값", t5.max(axis=0))
#열연산 최소값(결과는 열의 각 요소를 비교한 1차원 벡터임)
print("열연산 최소값", t5.min(axis=1))
<결과>
행연산 최대값 [4 5 6]
열연산 최소값 [1 4]
2) 요소 합계 sum( )
행렬 모든 요소의 합계를 구하는 sum이다. max, min과 마찬가지로 axis 파라미터 설정에 따른 계산값을 확인할 수 있다.
<코드>
print("모든 요소 합계 : ", t5.sum()) #요소의 총합계
print("행 합계 : ", t5.sum(axis=0)) #요소의 열합계
print("열 합계 : ", t5.sum(axis=1)) #요소의 행합계
<결과>
모든 요소 합계 : 21
행 합계 : [5 7 9]
열 합계 : [ 6 15]
3) 평균 mean( ) 과 중간값 median( )
요소의 평균이나 중간값을 구할 수도 있다. 주의할 점은 중간값의 경우 요소의 개수가 짝수이면 중간에 위치한 숫자 2개의 평균을 계산한다. 중간값의 경우 numpy.median(array) 형식으로 사용하므로 문법에 주의하도록 하자.
<코드>
print("평균 : ", t5.mean())
print("중간값 : ", np.median(t5))
<결과>
평균 : 3.5
중간값 : 3.5
t5의 요소가 짝수개이므로 (1,2,3,4,5,6) 중 중간 숫자 3,4의 평균값인 3.5가 결과값이다.
4) 최대값, 최소값 인덱스 구하기 : argmax( ), argmin( )
한 행렬의 최대값, 최소값 인덱스를 구하려면 argmax( )와 argmin( )을 사용한다. 인덱스는 0부터 시작하여 최대값과 최소값의 인덱스 번호를 출력하게 된다.
<코드>
print("최대값 인덱스 :", t5.argmax()) #최대값의 인덱스 출력
print("최소값 인덱스 :", t5.argmin()) #최소값의 인덱스 출력
<결과>
최대값 인덱스 : 5
최소값 인덱스 : 0
4. 논리 연산
논리 연산은 두개의 행렬을 비교하여 bool type의 결과(True, False)를 행렬로 출력해주는 부분이다. 여러가지 내용이 있으나 간단히 필요한 내용만 정리하고 자세한 내용은 하단의 참고링크로 대체한다.
비교를 위한 간단하게 (1,2) 행렬 2개를 선언해보았다.
<코드>
v1 = np.array([[1],[3]]) #(1,2) 2차원 행렬
v2 = np.array([[1],[2]]) #(1,2) 2차원 행렬
1) 행렬 비교 연산
말 그대로 2개의 행렬의 각 요소를 비교하여 각각 같은지 Boolean type으로 결과를 반환한다.
<코드>
v1 == v2
<결과>
array([[ True],
[False]])
만약 2개의 행렬이 완전히 같은 행렬인지 아닌지 비교하여 하나의 출력값으로 받고 싶다면 all 함수를 사용한다.
<코드>
np.all(v1==v2)
<결과>
False
2) 브로드캐스팅 비교 연산
다른 크기의 행렬 비교시에도 numpy는 브로드캐스팅을 적용하여 자동으로 연산한다. 위에서 정의했던 t5, t6 행렬을 그대로 가져와보았다.
#t5
array([[1, 2, 3],
[4, 5, 6]])
#t6
array([[1],
[2]])
<코드>
t5 == t6 #논리 연산시에도 자동으로 브로드캐스팅하여 연산 된다.
<결과>
array([[ True, False, False],
[False, False, False]])
위 결과에서 보듯이 크기가 작은 t6 행렬을 자동을 브로드캐스팅하여 크기가 큰 t5 기준인 (2,3)으로 만든다.
[1] -> [1] [1] [1]
[2] -> [2] [2] [2]
참고링크
1. https://ebbnflow.tistory.com/159
[파이썬패키지] 딥러닝을 위한 Numpy2 - 행렬의 연산
앞선 포스팅에서 2020/03/05 - [SW개발/Framework Library] - [파이썬패키지] 딥러닝을 위한 Numpy 공부1 - Numpy기초 [파이썬패키지] 딥러닝을 위한 Numpy 공부1 - Numpy기초 ● Numpy란 넘파이(Numpy)는 C로 구..
ebbnflow.tistory.com
2. '파이토치로 시작하는 딥러닝 입문' - https://wikidocs.net/52460
위키독스
온라인 책을 제작 공유하는 플랫폼 서비스
wikidocs.net
'코딩 > 데이터분석' 카테고리의 다른 글
[Python/파이썬] matplotlib 2편 : 그래프 시각화 y축 숫자가 섞여서 나오는 문제 해결 (0) | 2022.11.10 |
---|---|
[Python/파이썬] 필요한 부분만 정리하는 matplotlib 1편 (0) | 2021.08.15 |
[Python/파이썬] Numpy 기초 1편 : Array 생성 및 인덱싱,슬라이싱 (0) | 2021.06.29 |
[Python/파이썬] Pandas 기초 정리 : 원소 바꾸기, dropna(), fillna() (0) | 2021.04.13 |
[Python/파이썬] Pandas 기초 정리 : Dataframe 행, 열 삭제하기(drop 함수) (2) | 2021.04.11 |