(3-1) Numpy

Yongjoo Lee·2020년 12월 14일
0
post-thumbnail

Numpy

💡np.array() 의 인자는 하나! (리스트나 튜플 형태로 넘겨주어야 함)

벡터와 스칼라 연산

벡터의 각 원소에 대해서 연산을 진행

x=(123)c=5x=\begin{pmatrix}1\\2\\3\end{pmatrix}\hspace{1em}c=5

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F3af93a53-59b6-48fe-9278-cb139b361d12%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F3af93a53-59b6-48fe-9278-cb139b361d12%2Fimage.png)

벡터와 벡터 연산

벡터의 같은 인덱스끼리 연산이 진행됨!

y=(135)z=(2920)y=\begin{pmatrix}1\\3\\5\end{pmatrix}\hspace{1em}z=\begin{pmatrix}2\\9\\20\end{pmatrix}

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F2638eca0-4187-4469-a030-29862215566a%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F2638eca0-4187-4469-a030-29862215566a%2Fimage.png)

Array의 Indexing, Slicing

Python의 리스트와 유사하게 진행

W=(123456789101112)W=\begin{pmatrix}1&2&3&4\\5&6&7&8\\9&10&11&12\end{pmatrix}

Array의 Broadcasting

Numpy가 연산을 진행하는 특수한 방법

기본적으로 같은 Type의 data에 대해서만 연산이 적용가능

하지만 만약 피연산자가 연산 가능하도록 변환이 가능하다면 연산이 가능.
이를 Broadcasting이라고 한다.

  1. M×N,M×1M \times N, M \times 1

    (3 x 3)와 (3 x 1)를 연산하면 3 x 1을 3 x 3 으로 차원 수를 맞추고 연산을 한다.

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fd65699aa-4c50-4b02-b323-bdd32643a762%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fd65699aa-4c50-4b02-b323-bdd32643a762%2Fimage.png)

  2. M×N,1×NM \times N, 1 \times N

    (3 x 3)와 (1 x 3)를 연산하면 1 x 3을 3 x 3 으로 차원 수를 맞추고 연산을 한다.

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F64eb5330-6538-4c01-8630-5ba73819dd02%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F64eb5330-6538-4c01-8630-5ba73819dd02%2Fimage.png)

  3. M×1,1×NM \times 1, 1 \times N

    (3 x 1)와 (1 x 3)를 연산하면 둘 다 3 x 3 으로 차원 수를 맞추고 연산을 한다.

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fc8b8c20e-35f1-4046-b20f-4362dfb60b51%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fc8b8c20e-35f1-4046-b20f-4362dfb60b51%2Fimage.png)

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Ff88c4adc-3de5-42ee-8348-fa358199cc24%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Ff88c4adc-3de5-42ee-8348-fa358199cc24%2Fimage.png)

Numpy 와 선형대수

A. Basics

영벡터(영행렬)

  • 원소가 모두 0인 벡터(행렬)
  • np.zeros(dim)을 통해 생성, dim은 값 혹은 튜플(, )
np.zeros(2)
# array([0., 0.])

np.zeros((3, 3))
# array([[0., 0., 0.],
#        [0., 0., 0.],
#        [0., 0., 0.]])

일벡터(일행렬)

  • 원소가 모두 1인 벡터(행렬)
  • np.ones(dim)을 통해 생성, dim은 값 혹은 튜플(,)
np.ones(2)
# array([1., 1.])

np.ones((3, 3))
# array([[1., 1., 1.],
#        [1., 1., 1.],
#        [1., 1., 1.]])

대각행렬(diagonal matrix)

  • main diagonal을 제외한 성분이 0인 행렬
  • np.diag(main_diagonal)을 통해 생성
np.diag((2, 4))
# array([[2, 0],
#        [0, 4]])

np.diag((1, 3, 5))
# array([[1, 0, 0],
#        [0, 3, 0],
#        [0, 0, 5]])

항등행렬(identity matrix)

  • main diagonal이 1인 대각행렬
  • np.eye(n[, dtype=float])를 사용
np.eye(2, dtype=int)
# array([[1, 0],
#        [0, 1]])

np.eye((3, dtype=float))
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])

*dtype: data type, (dtype=int, uint, float, complex, ...)

행렬곱(dot product)

  • 행렬간에 정의되는 곱 연산
  • np.dot(), @ 사용
mat_1 = np.array([[1, 4], [2, 3]])
mat_2 = np.array([[7, 9], [0, 6]])

mat_1.dot(mat_2)
# array([[ 7, 33],
#        [14, 36]])

mat_1 @ mat_2
# array([[ 7, 33],
#        [14, 36]])

B. Furthermore

트레이스(trace)

  • main diagonal의 합
  • np.trace()를 사용
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

arr
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

arr.trace()
# 15

np.eye(2, dtype=int).trace()
# 2

행렬식(determinant)

adbcad-bc

  • 행렬을 대표하는 값들 중 하나 → 선형변환
  • 선형변환 과정에서 Vector의 Scaling 척도
  • np.linalg.det() 으로 계산
arr_2 = np.array([[2, 3], [1, 6]])

arr_2
# array([[2, 3],
#        [1, 6]])

np.linalg.det(arr_2)
# 9.000000000000002
arr_3 = np.array([[1, 4, 7], [2, 5, 8], [3, 6, 9]])

arr_3
# array([[1, 4, 7],
#        [2, 5, 8],
#        [3, 6, 9]])

# 1(5 * 6 - 6 * 8) - 4(2 * 9 - 3 * 8) + 7(2 * 6 - 3 * 5)
# -3 + 24 - 21
# 0

np.linalg.det(arr_2)
# 0.0

⭐행렬식 값이 0이면 선형변환 과정에서 차원에 손실이 발생한다!

역행렬(inverse matrix)

(abcd)=1adbc(dbca)\begin{pmatrix}a&b\\c&d\end{pmatrix} = {\Large\frac{1}{ad-bc}}\begin{pmatrix}d&-b\\-c&a\end{pmatrix}

  • 행렬 A에 대해 AB=BA=IAB = BA = I 를 만족하는 행렬 B(=A1)B (= A^{-1})
  • np.linalg.inv()을 사용
mat = np.array([[1, 4], [2, 3]])

mat
# array([[1, 4],
#        [2, 3]])

mat_inv = np.linalg.inv(mat)
# array([[-0.6,  0.8],
#        [ 0.4, -0.2]])

mat @ mat_inv
# array([[1., 0.],
#        [0., 1.]])

고유값과 고유벡터(eigenvalue and eigenvector)

Ax=λx(AλI)x=0Ax = \lambda x \hspace{1em}\Rightarrow \hspace{1em} (A-\lambda I)x = 0

  • 정방행렬 An×nA_{n\times n}에 대하여 Ax=λxAx=\lambda x를 만족하는 λ\lambda와 x를 각각 고유값과 고유벡터라고 한다.
  • np.linalg.eig()로 계산
mat = np.array([[2, 0, -2], [1, 1, -2], [0, 0, 1]])

mat
# array([[ 2,  0, -2],
#        [ 1,  1, -2],
#        [ 0,  0,  1]])

mat_linalg.eig(mat)
# (array([1., 2., 1.]),
#  array([[0.        , 0.70710678, 0.89442719],
#         [1.        , 0.70710678, 0.        ],
#         [0.        , 0.        , 0.4472136 ]]))

🔥고유값과 고유벡터가 나오는데,

고유값은 고유벡터의 열벡터에 대한 고유값이다.

🔎Validation

eig_val, eig_vec = np.linalg.eig(mat)

eig_val
# array([1., 2., 1.])

eig_vec
# array([[0.        , 0.70710678, 0.89442719],
#        [1.        , 0.70710678, 0.        ],
#        [0.        , 0.        , 0.4472136 ]])

mat @ eig_vec[:, 0] # Ax
# array([0., 1., 0.])

eig_val[0] * eig_vec[:, 0] # (lambda)x
# array([0., 1., 0.])

📌Numpy 정리

  • Numpy 연산

    • Vector - Scalar : elementwise! (+, -, *, /)
    • Vector - Vector : elementwise / broadcasting (+, -, *, /)
    • Indexing & Slicing
  • Numpy 와 선형대수

    1. basics
      • 영벡터 : .zeros()
      • 일벡터 : .ones()
      • 대각행렬 : .diag()
      • 항등행렬 : .eye()
      • 행렬곱 : @ / .dot()
    2. furthermore
      • 트레이스 : .trace()
      • 행렬식 : .linalg.det()
      • 역행렬 : .linalg.inv()
      • 고유값 : .linalg.eig()

Exercises🏃‍♂️

  1. 어떤 벡터가 주어졌을 때 L2 norm을 구하는 함수 get_L2_norm()을 작성하세요

    • 매개변수 : 1차원 벡터(np.array)
    • 반환값 : 인자로 주어진 벡터의 L2 Norm 값(number)
    import numpy as np
    
    mat = np.array([1,2,3,4])
    
    def get_L2_norm(mat):
        return np.linalg.norm(mat, ord=2)
    
    print(get_L2_norm(mat))
    # 5.477225575051661
  2. 어떤 행렬이 singular matrix 인지 확인하는 함수 is_singular()를 작성하세요

    • 매개변수 : 2차원 벡터(np.array)
    • 반환값 : 인자로 주어진 벡터가 singular하면 True, non-singular하면 False를 반환
    import numpy as np
    
    mat_1 = np.array([[1,2],[3,4]])
    mat_2 = np.array([[1,2],[2,4]])
    
    def is_singular(mat):
        return True if np.linalg.det(mat) == 0 else False
    
    print(is_singular(mat_1))
    # False
    print(is_singular(mat_2))
    # True
profile
하나씩 정리하는 개발공부로그입니다.

0개의 댓글