- Numpy
- Numpy는 는 벡터 및 행렬 연산에 있어서 매우 편리한 기능을 제공하는 파이썬 라이브러리이다
- 넘파이 기본 사용 예제
import numpy as np
#기본 배열 선언
A = np.array([[1,2],[2,3]])
#넘파이 베열의 수 확인 = np.shape()
print(np.shape(A))
#벡터 스칼라 연산
x = np.array([1])
y = 3
print("스칼라 벡터 덧셈 {}".format(x+y))
print("스칼라 벡터 곱셈 {}".format(x*y))
- 벡터와 벡터의 연산
- 벡터와 벡터의 연산에서의 주의 사항은 행과 열이 같아야 재대로 된 연산이 가능하다
- 추후에 나올 브로드캐스팅이 있는데 그건 추후에 기술
#벡터 벡터 연산
#벡터 연산은 행과 열이 모두 일치할 때 가능
x = np.array([1,2,3])
y = np.array([4,5,6])
print("스칼라 벡터 덧셈 {}".format(x+y))
print("스칼라 벡터 곱셈 {}".format(x*y))
- 넘파이의 인덱싱과 슬라이싱
- 기본적으로 파이썬과 같지만 2차원 이상 일 때 대괄호 연속해서 치는 python코드와 달리 한 대괄호 내에서 처리한다
#파이썬 indexing과 유사
x = np.array([[1,2,3,4],[2,3,4,5],[4,5,6,7]])
print(x[0,0])
print(x[1,2])
#파이썬 Slicing과 유사
x = np.array([[1,2,3,4],[2,3,4,5],[4,5,6,7]])
print(x[0:2, 0:2])
print(x[0:2])
- 넘파이의 브로드캐스팅
- 행과 열과 같은 길이가 아니면 연산이 원하는 대로 안 나올 수 있는데 이를 해결하기 위해 브로드캐스팅을 넘파이에서 해준다
- 브로드캐스팅이란 피연산자를 복제해 같은 data type으로 변형 시킬 수 있으면 복제해서 연산을 실행하는 것이다
- 예를들어 [[1,2],[1,1]]에 [0,1]을 더하면 1열 뿐만 아니라 2열도 [0,1]과의 연산을 하는 것이다
#Array Broadcating은 피연산자를 복제해 같은 data type으로 변형 시킬 수 잇으면 그리한대요~~
#열 복사
a = np.array([[1, 2, 3], [4,5,6], [7,8,9]])
x = np.array([0,1,0])
x = x[:, None] #x를 전치
print(a+x)
#행 복사
a = np.array([[1, 2, 3], [4,5,6], [7,8,9]])
x = np.array([0,1,-1])
print(a*x)
- 영 벡터(행렬)
- 모든 원소의 값이 0인 벡터(행렬)
- 'np.zeros(dim)'을 통해 생성 / dim은 값, 혹은 튜플(,)
- 일벡터도 동일하게 ones통해 생성
print(np.zeros(3))
print(np.zeros((3,3,3)))
print(np.ones(3))
- 대각행렬
- main diagonal을 제외한 성분이 0인 행렬
- 'np.diag'(main_diagonal <- tuple)을 통해 생성
print(np.diag((2, 4)))
print(np.diag((1,3,5)))
- 항등 행렬
- main diagonal이 1인 대각 행렬
- 'np.eye(length, dtype = type)'을 통해 생성
- dtype의 default = float
print(np.eye(3, dtype = int))
- ★ 행렬곱
- 행렬 곱은 n * r , r * m 일때 r이 서로 같아야 연산 가능
- 행렬의 곱은 * 기호가 아니라 @를 통해 연산한다
- 'A.dot(B)'로도 사용 가능 단 3차원이상은 @ 과 dot은 다르게 연산 된다
A = np.array([[1, 2], [3,5]])
B = np.array([[1, 3], [2,4]])
print(A.dot(B))
print(A @ B)
- trace
- Main diagonal의 합
- 'np.trace()'사용
A = np.array([[1,2,5],[2,4,1]])
print(A.trace())
print(np.eye(2, dtype = int).trace())
- 행렬식
- 행렬을 대표하는 값들 중 하나 -> 선형 변환
- 'np.linalg.det()'으로 계산
arr_3 = np.array([[1,4,7],[2,5,8],[3,6,9]])
print(np.linalg.det(arr_3))
- 역행렬
- A에 대해 AB = BA를 만족하는 행렬
- 'np.linalg.inv()'로 계산
arr_2 = np.array([[1, 2], [3, 5]])
arr_inv = np.array([[1, 2], [3,5]])
print(arr_inv)
#검증
print(arr_2 @ arr_inv)
- 고유값과 고유벡터
- 정방행렬 A에 대해 Ax(\lambda)x를 만족하는 상수 (\lambda)와 이에 대응되는 벡터
- 'np.linalg.eig()'로 계산
mat = np.array([[2, 0, -2], [1, 1, -2], [0, 0, 1]])
print(mat)
print(np.linalg.eig(mat))
#검증
eig_val , eig_vec = np.linalg.eig(mat)
print(mat @ eig_vec[:, 0]) # Ax
print(eig_val[0] * eig_vec[:,0])# (lambda)x
- Norm
- Norm 은 벡터의 크기(혹은 길이)를 측정하는 방법
- L1 Norm: 각 벡터의 원소의 절대값들의 합
- L2 Norm: 각 벡터를 잇는 선분의 길이
def get_L2_norm(arr):
return np.linalg.norm(arr)
A = np.array([1,2,3,4,5])
print(get_L2_norm(A))
- 특이 행렬
- 역행렬이 존재하지 않는 행렬
- 역행렬이 존재하지 않기 위해서는 행렬식(Determinant)이 0이 되어야 한다.
def singular_matrix(arr):
return True if np.linalg.det(arr) == 0 else False
A = np.array([[1,4,0],[2,5,0],[3,6,0]])
print(singular_matrix(A))