목차
파이썬에서 행렬과 벡터는 numpy의 ndarray를 이용하여 표현할 수 있습니다. 행렬과 벡터를 조작하고 계산하기 위해서는 연산자를 사용해야 하는데 파이썬의 기본 연산자를 이용해도 되고 numpy에서 제공하는 함수를 이용할 수도 있습니다. 이번에는 파이썬의 행렬과 벡터를 계산하기 위한 연산자에 대해 정리해 보도록 하겠습니다.
1. 행렬과 벡터 만들기
행렬과 벡터는 ndarray를 사용하여 생성할 수 있습니다. 대괄호인 '['과 ']'를 사용하여 표현하지만 파이썬의 리스트와 혼동하면 안 됩니다. 행렬과 벡터로 만들기 위해서는 'np.array([[1, 2], [3, 4]])'나 'np.array([6, 7])'와 같이 np.array() 함수를 사용해야 합니다. 만일 '[[1, 2], [3, 4]]'나 '[6, 7]'와 같이 정의한다면 그냥 리스트를 만들게 됩니다.
matrix = np.array([[1, 2], [3, 4]])
vector = np.array([6, 7])
list1 = [[1, 2], [3, 4]]
list2 = [6, 7]
print(matrix, '\n', type(matrix), '\n')
print(vector, '\n', type(vector), '\n')
print(list1, '\n', type(list1), '\n')
print(list1, '\n', type(list2), '\n')
#[[1 2]
# [3 4]]
# <class 'numpy.ndarray'>
#[6 7]
# <class 'numpy.ndarray'>
#[[1, 2], [3, 4]]
# <class 'list'>
#[[1, 2], [3, 4]]
# <class 'list'>
2. 행렬의 사칙연산
NxN의 행렬이 있을 경우 같은 크기의 행렬끼리는 사칙연산을 적용할 수 있습니다. 이때는 행렬의 각 요소들끼리 사칙연산이 적용됩니다. ndarray 타입의 데이터에서는 사칙연산이 가능하지만 만일, 리스트 형태라면 하나의 리스트에 다른 리스트의 요소를 삽입하는 결과가 됩니다.
vector1 = np.array([6, 7])
vector2 = np.array([8, 9])
vec_sum = vector1 + vector2
list1 = [6, 7]
list2 = [8, 9]
list_sum = list1 + list2
print(vec_sum)
print(list_sum)
[14 16]
[6, 7, 8, 9]
2x2의 행렬이 두 개가 있을 때 두 행렬의 사칙연산은 아래의 이미지와 같은 결과가 됩니다.
3. 행렬과 벡터 곱
행렬 'A'와 벡터 'v'가 있다고 할 때, 행렬끼리의 곱은 AA로 행렬과 벡터의 곱은 Av로 나타냅니다. 이를 파이썬에서 구현하기 위해서는 dot함수를 쓰거나 행렬곱 연산자 '@'를 사용할 수 있습니다.
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
v = np.array([6, 7])
r1 = np.dot(A, B)
r11 = A @ B
r2 = np.dot(B, A)
r3 = np.dot(A, v)
r4 = np.dot(v, A)
print(r1)
print(r11, '\n')
print(r2)
print(r3)
print(r4)
# [[19 22]
# [43 50]]
# [[19 22]
# [43 50]]
# [[23 34]
# [31 46]]
# [20 46]
# [27 40]
위의 코드에서 'np.dot' 함수 대신 '@'연산자를 사용할 경우 같은 결과가 나오는 것을 확인할 수 있습니다. 행렬곱은 두 개의 행렬이나 벡터의 위치에 따라 그 결과가 달라지니 사용에 주의를 해야 합니다. 벡터의 경우 수직, 수평을 알아서 계산해 주니 굳이 transpose를 해주지 않아도 됩니다.
4. 행렬 조작 함수
행렬을 조작하거나 행렬의 특성값을 계산해 주는 함수들이 있습니다. 행렬의 전치를 계산해 수는 'transpose', 역행렬을 구해주는 'inv', 행렬의 행렬식(determinant)을 계산하는 'det', 행렬이나 벡터의 크기를 계산하는 'norm' 함수들이 있습니다. 'transpose'의 경로 'A.T'와 같이 '.T'를 사용해도 됩니다.
행렬 조작 함수의 사용은 numpy의 함수도 있지만 numpy.linalg의 함수들도 있습니다. 다음은 각 조작 함수의 사용법입니다.
r1 = np.transpose(A)
r2 = A.T #transpose
r3 = np.linalg.inv(A) #inverse
r4 = np.linalg.det(A) #determinant
r5 = np.linalg.norm(A)
print(r1, '\n')
print(r2, '\n')
print(r3, '\n')
print(r4, '\n')
print(r5, '\n')
# [[1 3]
# [2 4]]
# [[1 3]
# [2 4]]
# [[-2. 1. ]
# [ 1.5 -0.5]]
# -2.0000000000000004
# 5.477225575051661
5. 마치며
이번 포스팅에서는 행렬 요소들끼리의 사칙연산을 계산하는 법과, 행렬 곱에 대해 내용 정리와 예제 코드를 만들어 보면서 정리하였습니다. 행렬 조작 함수에 대해서도 알아보았고 사용 시 주의사항도 같이 정리해 봤습니다. 행렬 곱을 의미하는 'numpy.dot'은 '@'로, 전치를 목적으로 하는 'numpy.transpose()'는 '.T'로 대체하여 사용할 수 있습니다.