본문 바로가기
프로그래밍/파이썬

넘파이(numpy)에서 행렬 연산

by 세인트 워터멜론 2021. 3. 12.

행렬의 덧셈과 뺄셈은 행렬의 구성 성분(element) 단위의 계산이다.

 

 

덧셈과 뺄셈에서는 기본적으로 두 행렬의 행과 열의 크기가 같아야 한다. 예를 들어 행렬 \(A\)와 \(B\)의 덧셈과 뺄셈은 다음과 같다.

 

\[ \begin{align} & A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}, \ \ \ B = \begin{bmatrix} 7 & 8 & 9 \\ 10 & 11 & 12 \end{bmatrix} \\ \\ & C=A+B = \begin{bmatrix} 8 & 10 & 12 \\ 14 & 16 & 18 \end{bmatrix} \\ \\ & D=A-B = \begin{bmatrix} -6 & -6 & -6 \\ -6 & -6 & -6 \end{bmatrix} \end{align} \]

 

import numpy as np

A = np.array([[1,2,3], [4,5,6]])
B = np.array([[7,8,9], [10,11,12]])

C = A+B
D = A-B

print("C=", C, "\nD=", D)

 

그러면 \(A+3\) 은? 행렬과 스칼라값과의 덧셈이다. 행렬의 모든 성분에 \(3\)을 더하라는 얘기다. 뺄셈도 마찬가지다.

 

\[ A+3 = \begin{bmatrix} 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} \]

 

print("A+3=", A+3)

 

그렇다면, 다음 덧셈은 가능할까?

 

\[ A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}, \ \ \ E = \begin{bmatrix} 1 \\ 2 \end{bmatrix} \]

 

일 때, \(A+E\) 는? 두 행렬의 행과 열의 길이가 다르므로 오류가 나야 맞지만 넘파이에서는 다음과 같이 행렬 \(E\)를 행렬 \(A\)의 열의 길이에 맞춰 늘려서 계산한다.

 

 

E = np.array([[1],[2]])
print("A+E=", A+E)

 

이와 같이 부족한 행과 열을 같은 성분으로 채워서 계산하는 방법을 브로드캐스팅(broadcasting)이라고 한다. 매트랩에서도 동일한 방법을 사용한다.

매트랩에서는 행렬의 곱셈이 기본적으로 행렬 단위로 계산되는 것에 비해, 넘파이에서는 행렬의 성분 단위로 계산된다.

 

\[ \begin{align} & A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}, \ \ \ B = \begin{bmatrix} 7 & 8 & 9 \\ 10 & 11 & 12 \end{bmatrix} \\ \\ & A \star B = \begin{bmatrix} 7 & 16 & 27 \\ 40 & 55 & 72 \end{bmatrix} \end{align} \]

 

print("A*B=", A*B)

 

행렬의 성분 단위 곱셈에도 브로드캐스팅이 적용된다.

행렬 곱셈을 하려면 행렬 \(A\)의 열과 행렬 \(B\)의 행의 길이가 같아야 한다. 넘파이에서 행렬 곱셈은 ndarray.dot 을 사용한다.

 

\[ AB^T = \begin{bmatrix} 50 & 68 \\ 122 & 167 \end{bmatrix} \]

 

G = A.dot(B.T)
print("AB^T=", G)

 

행렬의 모든 성분의 총합은 ndarray.sum() 을 사용한다.

 

print("A=", A, "\nA.sum=", A.sum())

 

행렬의 행 단위의 합은 ndarray.sum(axis=0), 열 단위의 합은 ndarray.sum(axis=1)을 사용한다. 행렬 A의 행 단위의 합은 [5 7 9]가, 열 단위의 합은 [6 15]인 1차원 어레이가 출력된다.

 

 

print(A.sum(axis=0), A.sum(axis=1))
print(A.sum(axis=0).shape, A.sum(axis=1).shape)

 

행렬의 모든 성분의 평균은 ndarray.mean() 을 사용한다. 행렬의 행 단위의 평균은 ndarray.mean(axis=0), 열 단위의 평균은 ndarray.mean(axis=1) 을 사용한다.

 

print(A.mean(), A.mean(axis=0), A.mean(axis=1))

 

행렬의 모든 성분의 최대값은 ndarray.max() 을 사용한다. 행렬의 행 단위의 최대값은 ndarray.max(axis=0), 열 단위의 최대값은 ndarray.max(axis=1) 을 사용한다.

 

print(A.max(), A.max(axis=0), A.max(axis=1))

 

최소값은 max 대신에 min 을 사용하면 된다.

 

 

 

댓글