전공 수업인 데이터 마이닝 오티날에 깜짝 코딩 테스트를 치뤘다. 50분 동안 2문제를 푸는 거였는데 생각보다 어려웠어서 코드를 정리하고 간다.
행렬곱이 뭘까?
두 행렬의 곱을 의미한다.
행렬곱은 일반적인 원소곱과 다르다. 뭔지 잘 모른다면 알아보고 오길 바란다.
넘파이 모듈을 사용한 행렬곱
import numpy as np
a=np.array([[2,3,0],[8,9,1],[7,0,5]])
b=np.array([[1,2,2],[1,2,1],[1,2,3]])
print(np.dot(a,b))
모듈을 사용하지 않은 행렬곱
클래스로 짜서 꽤 길어보이지만 핵심 코드는 run 메소드다.
class matrix_mul:
def __init__(self, a, b):
self.a=a
self.b=b
self.result=[[0 for j in range(len(b[0]))] for i in range(len(a))]
def run(self):
r=0
for i in range(len(self.a)):
for j in range(len(self.b[0])):
for k in range(len(self.b)):
r+=self.a[i][k]*self.b[k][j]
self.result[i][j]=r; r=0
def __str__(self):
return "{}".format(self.result)
if __name__=="__main__":
a=[[2,3,0],[8,9,1],[7,0,5]]
b=[[1,2,2],[1,2,1],[1,2,3]]
answer=matrix_mul(a,b)
answer.run()
print(answer)
일단 예제에 나온 행렬은 모양이 똑같아서 다른 행렬로 하겠다.
c=[[1,3,2],[4,0,1]]
d=[[1],[0],[5]]
def run(self):
r=0
for i in range(len(self.a)):
for j in range(len(self.b[0])):
for k in range(len(self.b)):
r+=self.a[i][k]*self.b[k][j]
self.result[i][j]=r; r=0
for문 구조?
행렬곱을 구하는 과정을 풀어서 보면 규칙이 있는 것이 보일 거다. 이 부분이 문제를 푸는 포인트다. 아마 많이 헷갈릴테니 직접 그려보는 것을 추천한다.
그림에서 다음의 도형을 친 것들은 그 모양이 똑같은 것들이다.
- 샤프로 동그라미
- 샤프로 세모
- 빨간색 동그라미
- 빨간색 세모
여기서 규칙을 찾을 수 있다. 빨간색 형광펜을 친 부분이 가장 바깥쪽 for문에 들어가고, 초록색으로 친 부분은 그 다음, 파란색 동그라미가 마지막 for문으로 들어간다. 아직 이해가 되지 않을 테니 코드를 들어가보자.
코드 리뷰
1. result[] 초기화
행렬이 2행 3열 * 3행 2열이면, 앞쪽 행렬의 열과 뒤쪽 행렬의 행의 값이 같아야 하고, 이때 두 행렬의 곱의 결과는 앞쪽 행렬의 행 * 뒤쪽 행렬의 열이라는 것을 알 것 이다.
self.result=[[0 for j in range(len(b[0]))] for i in range(len(a))]
참고로 빈 리스트를 만들 때 *연산자보다 for문을 쓰는 것을 추천한다. 이유는 아래 링크 참고.
https://sogogi1000inbun.tistory.com/33
2. for문
우리는 결과값인 result[0][0] 값부터 먼저 구할 거다. result[0][0] 값은 아래 그림의 값들을 모두 더했을 때 구할 수 있다.
- 가장 바깥쪽 for문은 a행렬의 행을 지정해준다.
- 2번째 for문은 a행렬의 열과 b행렬의 행을 지정해준다.
- 마지막 for문은 a행렬의 열을 지정해준다.
행렬곱 순서를 생각해보면 for문의 range값에 들어가는 값이 왜 저렇게 들어가는 지 이해하기 쉬울 것이다.
def run(self):
r=0
for i in range(len(self.a)):
for j in range(len(self.b[0])):
for k in range(len(self.b)):
r+=self.a[i][k]*self.b[k][j]
self.result[i][j]=r; r=0
아마 여기까지 읽어도 감이 잘 안 올텐데, 직접 써보고 코드를 돌려봐야 감이 올 거다. 그럼 아디오스
'python' 카테고리의 다른 글
[코딩] 제로부터 시작하는 selenium- 넷플릭스 크롤링 (python) (1) | 2022.03.27 |
---|---|
[코딩] 여러 파일에서 특정 키워드를 포함하는 파일 찾기(python) (0) | 2022.03.05 |
[코딩] 카카오톡 채팅방 분석, 빈도수 높은 단어 (0) | 2022.02.25 |
[python] konlpy 모듈 돌려버리기★colab에서 구글 드라이브 파일 가져오기 (0) | 2021.11.17 |
[자료구조] 리스트 (0) | 2021.04.04 |