이 글에서는 두 행렬을 곱하는 문제를 파이썬으로 해결하는 다양한 방법을 알아보겠습니다.
문제 정의
문제: 주어진 두 개의 행렬을 곱한 후 그 결과를 출력해야 합니다.
행렬 곱셈이 성립하려면 첫 번째 행렬의 열(column)의 개수와 두 번째 행렬의 행(row)의 개수가 같아야 한다는 조건을 반드시 만족해야 합니다. 예를 들어 m×n 행렬과 n×p 행렬을 곱하면 결과는 m×p 행렬이 됩니다.
이 조건이 참일 때 각 원소의 곱셈과 덧셈 연산을 통해 최종 결과가 계산됩니다.
그럼 실제 구현 예제를 통해 개념을 살펴보겠습니다.
방법 1 - 브루트 포스(중첩 반복문) 방식
가장 기본적인 방법은 세 개의 중첩 반복문을 사용하는 것입니다. 바깥쪽 반복문은 첫 번째 행렬의 행을 순회하고, 두 번째 반복문은 두 번째 행렬의 열을, 안쪽 반복문은 해당 행과 열의 원소들을 차례대로 곱하여 누적합니다.
예제 코드
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
B = [[5, 3, 3],
[6, 5, 4],
[0, 2, 0]
]
result = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
# 행(row) 기준으로 반복
for i in range(len(A)):
# 열(column) 기준으로 반복
for j in range(len(B[0])):
# 내부 요소들을 순회하며 곱셈 누적
for k in range(len(B)):
result[i][j] += A[i][k] * B[k][j]
for ele in result:
print(ele)실행 결과
[17, 19, 11] [50, 49, 32] [83, 79, 53]
방법 2 - zip 함수 활용하기
파이썬의 내장 함수인 zip()을 사용하면 코드를 훨씬 간결하게 작성할 수 있습니다. zip(*B)를 통해 두 번째 행렬의 전치(transpose)를 얻어 각 행과 열의 쌍을 손쉽게 처리할 수 있습니다.
예제 코드
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
B = [[5, 3, 3],
[6, 5, 4],
[0, 2, 0]
]
# 내장 zip 함수를 활용한 행렬 곱셈
result = [[sum(a * b for a, b in zip(A_row, B_col))
for B_col in zip(*B)]
for A_row in A]
for ele in result:
print(ele)실행 결과
[17, 19, 11] [50, 49, 32] [83, 79, 53]
마무리
이번 글에서는 파이썬에서 두 행렬을 곱하는 두 가지 방법을 배웠습니다. 중첩 반복문을 이용한 브루트 포스 방식은 로직을 명확하게 이해할 수 있다는 장점이 있고, zip 함수를 활용한 방식은 코드가 간결하고 파이써닉(Pythonic)하다는 장점이 있습니다. 또한 실무에서는 NumPy의 np.dot()이나 @ 연산자를 사용하면 더욱 빠르고 효율적으로 행렬 곱셈을 수행할 수 있으니 참고하시기 바랍니다.