파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi

매트랩에 익숙한 사용자가 파이썬을 사용하게 되면 불편한 점이 몇 가지가 있는데 그 중에서도 가장 불편한 것이 행렬에 관한 것이 아닐까 싶다. 행렬 생성부터 시작하여, 부분 선택, 성분 바꾸기, 행렬 확장, 행렬 연산에 이르기까지 다 불편한 것 같다. 하지만 파이썬을 쓰려면 넘파이 스타일의 행렬에 익숙해져야 한다.

넘파이에서는 행렬을 어레이(array)로 부른다. 넘파이의 어레이 클래스는 ndarray이다. n-dimensional array란 뜻이다. 고차원 어레이가 기본인 모양이다.

차원(dimension)은 우리가 일반적으로 얘기하는 행렬의 차원이다. 예를 들어서 2차원 어레이는 \(N\)행과 \(M\)열로 이루어진 \(N \times M\) 행렬이다. 3차원 어레이는 행과 열, 그리고 깊이가 있는 \(N \times M \times L\) 행렬을 의미한다. 이런 식으로 하면 4차원 어레이는 행과 열, 깊이, 그리고 페이지로 이루어진 \(N \times M \times L \times K\) 행렬이다.

보통 행이 1개 또는 열이 1개인 \(1 \times N\) 행렬 또는 \(N \times 1\) 행렬을 벡터라고 하며 이를 1차원 행렬이라고 하는데, 넘파이 어레이에서는 이들도 모두 2차원 어레이로 분류한다. 1차원 어레이는 행이나 열 표시없이 \(N\)개의 성분으로 구성된다.

넘파이에서는 차원을 axis 라고 부른다. axis=0 은 행이며, axis=1 은 열, axis=2 는 깊이, 이런 순서로 나간다.

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi

먼저 \(2 \times 3\) 행렬 \(A\) 를 생성해 보자.

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

어레이를 생성하려면 np.array 함수를 사용한다.

import numpy as np

A = np.array([[1,2,3], [4,5,6]])

넘파이 어레이에서 대괄호 기호 [ ]는 어레이(행렬)의 한 행으로 이해하면 된다. 그리고 대괄호 안의 성분은 열(column) 성분을 나타낸다고 보면 된다. 그래서 \(A\)는 바깥쪽 대괄호 안에 두개의 대괄호가 있는데 바깥쪽 대괄호는 어레이 시작, 안쪽의 첫번째 대괄호는 어레이의 첫번째 행, 두번째 대괄호는 두번째 행을 나타낸다. 어레이가 몇차원인지 알고 싶으면 ndarray.ndim 을, 각 axis의 길이(즉 행렬의 모양)를 알고 싶으면 ndarray.shape 를 이용한다.

print(A.ndim, A.shape)

결과는 2 와 (2,3) 이 나온다.

이번에는 다음과 같이 행벡터와 열벡터를 생성해 보자.

\[ a= \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} , \ \ b= \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix} \]

a = np.array([[1,2,3]])
b = np.array([[1], [2], [3]])
c = np.array([1, 2, 3])

여기서 c를 보면 대괄호가 1개 있다. 이렇게 하면 1차원 어레이가 생성된다. 차원을 보면

print(a.ndim, b.ndim, c.ndim)

a와 b는 2차원, c는 1차원이다. 어레이의 모양을 보면

print(a.shape, b.shape, c.shape)

a는 (1,3), b는 (3,1), c는 (3, ) 이라고 나온다. 성분이 모두 0인 어레이는 np.zeros를 이용하여 생성한다. 다음은 1차원 어레이, 2행3열의 2차원 어레이를 생성하는 예이다. 소괄호가 두 개가 있음에 주의해야 한다.

d1 = np.zeros(2)
d2 = np.zeros((2,3))

print("d1=", d1, "\nd2=", d2)

성분이 모두 1인 어레이는 np.ones를 이용하여 생성한다. 다음은 1차원 어레이, 3행2열의 2차원 어레이를 생성하는 예이다.

e1 = np.ones(2)
e2 = np.ones((3,2))

print("e1=", e1, "\ne2=", e2)

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi

Project : Py_EX

Python file : EX03_arraycal.py

Module : Numpy (as np)

IDE : PyCharm [설치방법]


공학분야를 다루다 보면 행렬(matrix)연산은 기본적으로 많이 다루게 되는데, matlab에서는 이를 굉장히 간단하게 다룰 수 있도록 함수 및 인터페이스가 잘 되어있다. 파이썬도 비슷한 능력을 갖고 있을거라고 생각하고 한 번 시도해보자.

파이썬에는 NumPy라는 패키지가 있다. 이놈을 설치하고 시작하자. 설치 방법은 전에 한번 설명한 바가 있으니 참고하자. [바로가기] NumPy가 무엇인지 궁금하다면 홈페이지를 한번 방문해서 둘러보는것을 추천한다.

NumPy

Powerful N-dimensional arrays Fast and versatile, the NumPy vectorization, indexing, and broadcasting concepts are the de-facto standards of array computing today. Numerical computing tools NumPy offers comprehensive mathematical functions, random number g

numpy.org

무려 올해 6월에 로고가 새로 제작되었다고 하니 한번 보고 넘어가자. 따끈따끈하다.

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi
NumPy의 새로운 로고

여기에서 내가 해보고 싶은 것은 행렬을 만들고 연산을 해보는 것이다. 예를들면

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi

우리는 이런 연산을 눈만 꿈벅거려도 금방 풀 수 있다. 한번 해보자.

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi

눈으로 풀었지만 이정도는 틀리기도 어렵다. 하지만 행렬수가 늘어나고 수가 복잡해지면 계산기를 쓰지 않을 수 없다. 우리의 고성능 계산기 파이썬으로 이 문제를 풀어보자.

## 행렬 생성

# matrix, array

NumPy에서 행렬을 만드는 방법은 두 가지가 있다.

  1. matrix로 행렬을 생성 (like matlab)
  2. array로 배열을 생성

이중 뭘 써야할까? 어떤 차이가 있는지 일단 한 번 만들어보자.

import numpy as np

a_matrix = np.matrix([[2, 5], [1, 3], [6, 1]])
print(a_matrix)

a_array = np.array([[2, 5], [1, 3], [6, 1]])
print(a_array)

결과는

[[2 5] 
 [1 3] 
 [6 1]]
[[2 5] 
 [1 3] 
 [6 1]]

로 완벽하게 같은 결과가 출력된다. 그런데 파이참에서 코드를 자세히 보면 뭔가 이상하다.

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi
파이참 코딩 화면 

 np.matrix  에 취소선이 그어져있고, 그 곳을 클릭하면 다음과 같은 설명을 확인할 수 있다.

즉, matrix의 하위 클래스는 행렬을 나타내거나 선형대수를 다루는데에 권장되는 방법이 아니라는 이야기 이고, URL을 따라가면 뜻밖의 좋은 페이지를 만날 수 있다. 특히 matlab 유저였던 파이썬 초보 사용자들에게는 무척이나 유익한 내용이니 시간을 내어서 한번 봐두면 좋겠다. matlab과 numpy의 함수들의 비교표가 아주 잘 정리되어 있고, matrix와 array의 장/단점도 잘 정리가 되어있다. 아예 프린트를 해서 책상에다 붙여두자.

NumPy for Matlab users — NumPy v1.19 Manual

Introduction MATLAB® and NumPy/SciPy have a lot in common. But there are many differences. NumPy and SciPy were created to do numerical and scientific computing in the most natural way with Python, not to be MATLAB® clones. This page is intended to be a

numpy.org

본론으로 돌아와서 결론적으로  numpy.matrix 는 더이상 권장되지 않으며 대신에  numpy.array 를 사용하라는 것이 NumPy의 권장사항이며 심지어  numpy.matrix 는 미래에는 아예 사라질지도 모른다고 한다. 그래도 아직 작동은 되는 것 같으니 없어지기 전에 한번 사용이나 해보자.  numpy.matrix 의 사용은 matlab과 굉장히 유사하다. [numpy.matrix 매뉴얼] 하지만 오해는 말자, 없어질 녀석이니 마지막으로 써보는 것이고 matlab에서 파이썬으로 넘어왔으니 앞으로 행렬 연산은 모두  numpy.array 를 사용해야겠다.

## 행렬 연산

# dot(), @

 numpy.matrix 를 사용한 행렬의 곱 연산 결과 위에서 눈대중으로 계산했던 결과가 그대로 출력된다. 데이터타입은 누군가가 궁금해 할 수 있을까봐 출력해 보았다.  type() 내장함수를 사용하고, 결과는 당연히  numpy.matrix 이다.

import numpy as np

a_matrix = np.matrix([[2, 5], [1, 3], [6, 1]])      # numpy.matrix를 사용하여 a행렬 생성
b_matrix = np.matrix([[3], [2]])                    # numpy.matrix를 사용하여 b행렬 생성
c_matrix = a_matrix*b_matrix                        # numpy.matrix의 행렬의 곱 연산
print(c_matrix)                                     # 행렬의 곱 연산 결과 출력
print(type(c_matrix))                               # matrix의 type 출력

[[16] 
 [ 9] 
 [20]]
<class 'numpy.matrix'>

numpy.array를 사용한 행렬의 곱 연산도 마찬가지의 결과를 얻을 수 있다. 해보자.

import numpy as np

a_array = np.array([[2, 5], [1, 3], [6, 1]])        # numpy.array를 사용하여 a행렬 생성
b_array = np.array([[3], [2]])                      # numpy.array를 사용하여 b행렬 생성
c_array = a_array @ b_array                         # numpy.array의 행렬의 곱 연산
print(c_array)                                      # 행렬의 곱 연산 결과 출력
print(type(b_array))                                # array의 type 출력

[[16] 
 [ 9] 
 [20]]
<class 'numpy.ndarray'>

같은 결과가 출력되며, array의 데이터 타입은 numpy.ndarray 이다. n-dimension array 라는 것이겠지. 여기에서 주목할 것은 행렬의 곱 연산 방법인데,  numpy.matrix 는  * 연산자가 행렬의 곱을 이야기 하지만  numpy.array 에서  * 연산자는 원소간의 곱, 즉 matlab에서  .*  연산자에 해당한다.  numpy.array 에서 행렬의 곱을 하기 위해서는  dot() 함수나  @ 연산자(python 3.5이상)을 사용한다. 이 내용은 위에서 언급한 링크(NumPy for Matlab Users)에 아주 자세히 설명되어 있다.


# 전체 코드

# 행렬 만들고 계산까지 해보기 20.09.14

import numpy as np

a_matrix = np.matrix([[2, 5], [1, 3], [6, 1]])      # numpy.matrix를 사용하여 a행렬 생성
b_matrix = np.matrix([[3], [2]])                    # numpy.matrix를 사용하여 b행렬 생성
c_matrix = a_matrix*b_matrix                        # numpy.matrix의 행렬의 곱 연산
print(c_matrix)                                     # 행렬의 곱 연산 결과 출력
print(type(c_matrix))                               # matrix의 type 출력

a_array = np.array([[2, 5], [1, 3], [6, 1]])        # numpy.array를 사용하여 a행렬 생성
b_array = np.array([[3], [2]])                      # numpy.array를 사용하여 b행렬 생성
c_array = a_array @ b_array                         # numpy.array의 행렬의 곱 연산
print(c_array)                                      # 행렬의 곱 연산 결과 출력
print(type(b_array))                                # array의 type 출력

numpy의 matrix, array를 이용하여 행렬을 생성하고 행렬의 곱 연산을 해보았다. 나중에 써먹기에 아직은 조금 부족한 느낌이 든다.  numpy.array 에 대해 조금 더 알아보자.

[Python] 행렬 만들고 연산까지 해보기2

Project : Py_EX Python file : EX03_arraycal.py (이어서) Module : Numpy (as np) IDE : PyCharm 이전 글 참조 [Python] 행렬 만들고 연산까지 해보기 Project : Py_EX Python file : EX03_arraycal.py Module..

generalbulldog.tistory.com

파이썬 행렬 만들기 - paisseon haenglyeol mandeulgi