반응형
numpy
- 파이썬에서 수치 해석을 위한 배열을 사용하는 표준 패키지입니다.
- 다차원 배열의 자료구조 클래스인 ndarray 클래스를 지원하며 벡터와 행렬을 사용하는 선형대수 계산에 주로 사용됩니다.
- 내부적으로 BLAS 라이브러리와 LAPACK 라이브러리를 사용하고 있으며 C로 구성된 CPython에서만 사용할 수 있습니다.
- 넘파이의 배열 연산은 C로 구현된 내부 반복문을 사용하기 때문에 파이썬 반복문에 비해 속도가 빠르며 벡터화 연산을 이용하여 간단한 코드로도 복잡한 선형 대수 연산을 수행 할 수 있습니다.
- 배열 인덱싱을 사용한 질의 기능을 이용하여 간단한 코드로도 복잡합 수식을 계산할 수 있습니다.
▶ 리스트의 단점
- 많은 숫자 데이터를 하나의 변수에 넣고 관리할 때 속도가 느리며 메모리를 많이 차지 합니다.
이 리스트의 단점을 Array(배열)를 사용함으로써 해결할 수 있습니다.
▶ Array
- 모든 원소가 같은 자료형이어야 합니다.
- 원소의 갯수를 바꿀 수 없습니다.
▶ 넘파이 텐서 연산의 장점
- C와 유사한 형태로 메모리를 관리하면서 C와 같은 연산속도로 계산할 수 있습니다.
- 메모리 구조상 요소들이 붙어 있기 때문입니다.
- 파이썬의 가장 큰 특징인 동적 타이핑을 포기했지만, C로 구현되어 있어 배열 연산에 있어 매우 큰 성능적 우위를 확보합니다.
- 대용량 배열 연산에서 넘파이가 사실상 표준으로 사용됩니다.
- 연결 연산처럼 여러 배열을 붙이는 연산에서는 일반적인 리스트에 비해 느립니다.
- 메모리 탐색과정으로 새로운 공간을 잡아야 하기 때문입니다.
ndarray & tensor
▶ ndarray(넘파이 배열)
- 넘파이에서 텐서 데이터를 다루는 객체
▶ 텐서(tensor)
- 선형대수의 데이터 배열
- 랭크(rank)에 따라 이름이 다릅니다.
Python List와 Numpy Array의 차이점
▶ 텐서 구조에 따라 Array를 생성합니다.
- 배열의 모든 구성 요소에 값이 존재해야 합니다.
- 동적 타이핑을 지원하지 않습니다.
- 하나의 데이터 타입만 사용합니다.
- 데이터를 메모리에 연속적으로 나열합니다.
- 각 값의 메모리 크기가 동일합니다.
- 검색이나 연산 속도가 리스트에 비해 훨씬 빠릅니다.
numpy 패키지 import
import numpy as np
numpy Array 생성
▶ 생성
test_array = np.array([1, 4, 5, '8'], float)
print(test_array)
print(type(test_array[3]))
print(test_array.dtype) # 전체 데이터 타입 반환
print(test_array.shape) # 배열의 shape(구조)를 반환, (n차원)로 출력됩니다.
# [1. 4. 5. 8.]
# <class 'numpy.float64'>
# float64
# (4,)
numpy Array shape(구조)
▶ 2랭크의 배열 구조
matrix = [[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]]
np.array(matrix, int).shape
# (3, 4)
▶ 3랭크의 배열 구조
matrix = [[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]]]
print(np.array(matrix, int).shape)
print(np.array(matrix, int).ndim) #number of dimension
print(np.array(matrix, int).size)
# (3, 3, 4)
# 3
# 36
dtype
np.array의 매개변수로 numpy array의 데이터 타입을 지정합니다.
- 변수가 사용하는 데이터 타입의 메모리 크기가 정해집니다.
np.array([[1, 2, 3.5], [4, 5, 6.5]], dtype = int)
# array([[1, 2, 3],
# [4, 5, 6]])
np.array([[1, 2, 3.5], [4, 5, 6.5]], dtype = float)
# array([[1. , 2. , 3.5],
# [4. , 5. , 6.5]])
▶ itemsize
- 배열 각 맴버의 바이트 크기를 리턴합니다.
import sys
np.array([[1, 2, 3.5], [4, 5, 6.5]], dtype = np.float32).itemsize
# 4
# byte가 생략됨
import sys
np.array([[1, 2, 3.5], [4, 5, 6.5]], dtype = np.float64).itemsize
# 8
# byte가 생략됨
※ Int = 4byte, float = 8byte
reshape()
- 배열의 구조를 변경하고 랭크를 조절합니다.
- 차원 인자 값에 -1을 입력하면 전체 요소의 개수를 고려하여 마지막 차원이 자동으로 지정됩니다.
▶ 기본 문법
변경할 배열.reshape(변경할 차원)
np.reshape(변경할 배열, 변경할 차원)
x = np.array([[1, 2, 5, 8], [1, 2, 5, 8]])
x.reshape(-1,)
# array([1, 2, 5, 8, 1, 2, 5, 8])
x = np.array([[1, 2, 5, 8], [1, 2, 5, 8]])
x.reshape(2, 2, 2)
# array([[[1, 2],
# [5, 8]],
#
# [[1, 2],
# [5, 8]]])
x = np.array(range(8))
x.reshape(2, -1)
# array([[0, 1, 2, 3],
# [4, 5, 6, 7]])
flatten()
- 데이터의 개수는 그대로 존재합니다
- 배열의 구조만 변합니다.
x = np.array.(range(8)).reshape(2, 2, 2)
x.flatten()
# array([0, 1, 2, 3, 4, 5, 6, 7])
Indexing & Slicing
▶ Indexing
- 리스트에 있는 값의 상대적인 offset(주소)로 값에 접근합니다.
- 넘파이 배열의 인덱스 표현에는 ','을 지원합니다.
- [a][b] 또는 [a,b] 형태
- 3차원 텐서 이상은 shape에서 출력되는 랭크 순서대로 인덱싱에 접근합니다.
x = np.array([[1, 2, 3], [4, 5, 6]], int)
print(x[0][2])
print(x[0,2])
# 3
# 3
▶ slicing
- 인덱스를 사용하여 리스트 일부를 잘라내어 반환합니다.
- 넘파이 배열은 행과 열을 나누어 슬라이싱 할 수 있습니다.
x = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], int)
print(x[:,2:])
# [[ 3 4 5]
# [ 8 9 10]]
print(x[1, 1:3])
# [7 8]
print(x[1:3])
# [[ 6 7 8 9 10]]
Step
- 리스트에서 데이터의 요소를 호출 할 때 데이터를 건너 뛰면서 반환합니다.
- [시작 인덱스 : 마지막 인덱스 : 증가값]
- 각 랭크에 있는 요소별로 모두 적용 할 수 있습니다.
x = np.array(range(15), int).reshape(3, -1)
print(x)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
print(x[:,::2])
# [[ 0 2 4]
# [ 5 7 9]
# [10 12 14]]
print(x[::2,::3])
# [[ 0 3]
# [10 13]]
arange
- 배열을 생성하는 함수입니다.
- ragne 함수와 같이 차례대로 값을 생성합니다.
- range 함수와 달리 증가값에 실수형이 입력되어도 값을 생성 할 수 있습니다.
- 소수점 값을 주기적으로 생성할 때 유용합니다.
▶ 구문
np.arange(시작 인덱스, 마지막 인덱스, 증가값);
print(np.arange(10))
print(np.arange(-5, 5))
print(np.arange(0, 5, 0.5))
# [0 1 2 3 4 5 6 7 8 9]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5]
ones, zeros, empty
- 배열을 생성합니다.
- 생성 시점에 dtype을 지정해주면 해당 데이터 타입으로 배열을 생성합니다.
▶ ones
- 1로만 구성된 넘파이 배열을 생성합니다.
- 사전에 shape값을 넣어서 원하는 크기의 넘파이 배열을 생성합니다.
▶ zeros
- 0으로만 구성된 넘파이 배열을 생성합니다.
▶ empty
- 활용 가능한 메모리 공간을 확보하여 반환합니다.
- ones와 zeros는 먼저 shape의 크기만큼 메모리를 할당하고 그곳에 값을 채웁니다.
- 해당 메모리 공간에 값이 남았을 경우 그 값을 함께 반환합니다.
- 생성될 때마다 다른 값을 반환합니다.
▶ 구문
print(np.ones(shape=[5, 2], dtype=np.int8))
# [[1 1]
# [1 1]
# [1 1]
# [1 1]
# [1 1]]
print(np.zeros(shape=[2, 2], dtype=np.float32))
# [[0. 0.]
# [0. 0.]]
ones_like, zeros_like, empty_like
▶ ones_like
- 기존 넘파이 배열과 같은 크기로 만들어 내용을 1로 채웁니다.
▶ zeros_like
- 기존 넘파이 배열과 같은 크기로 만들어 내용을 0으로 채웁니다.
▶ empty_like
- 기존 넘파이 배열과 같은 크기로 만들어 빈 상태로 만듭니다.
▷ 예문
x = np.arange(12).reshape(3, 4)
print(x)
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.ones_like(x))
# [[1 1 1 1]
# [1 1 1 1]
# [1 1 1 1]]
print(np.zeros_like(x))
# [[0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
print(np.empty_like(x))
# [[0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]]
identity, eye, diag
▶ identity
- 단위 행렬을 생성합니다.
- 매개변수 n으로 n x n 단위 행렬을 생성합니다.
▷ 예문
print(np.identity(n=3, dtype=int))
# [[1 0 0]
# [0 1 0]
# [0 0 1]]
print(np.identity(n=4, dtype=int))
#[[1 0 0 0]
# [0 1 0 0]
# [0 0 1 0]
# [0 0 0 1]]
▶ eye
- 시작점과 행렬 크기를 지정, 단위 행렬을 생성합니다.
- N = 행의 개수, M = 열의 개수
- k = 열의 값을 기준으로 시작하는 인덱스
▷ 예문
print(np.eye(N=3, M=5, k=2))
# [[0. 0. 1. 0. 0.]
# [0. 0. 0. 1. 0.]
# [0. 0. 0. 0. 1.]]
▶ diag
- 행렬의 대각선분 값을 추출합니다.
▷ 예문
print(np.diag(np.arange(9).reshape(3, 3)))
# [0 4 8]
print(np.diag(np.arange(9).reshape(3, 3), k=1))
# [1 5]
통계 분석 함수
▶ uniform()
- 균등분포 함수
▷ 구문
np.uniform(시작값, 끝값, 데이터 개수)
▷ 예문
print(np.random.uniform(0, 5, 10))
# [0.52675772 0.42216318 3.88471858 2.38202763 3.23275871 2.58250078
# 3.81355672 4.66374263 1.46639956 3.29314779]
▶ normal()
- 정규분포 함수
▷ 구문
np.normal(평균값, 분산, 데이터 개수)
▷ 예문
print(np.random.normal(0, 2, 10))
# [ 1.67769499 2.65559914 -0.83006297 -0.54458485 1.96107166 1.43042317
# -1.4927319 -1.8952236 -0.91212602 0.83006339]
x = np.random.normal(0, 2, 10)
print(np.mean(x)) # 평균
print(np.std(x)) # 표준편차
print(np.var(x)) # 분산
# 0.37585327103539473
# 1.1455876931248066
# 4.6868580082283
x = np.random.normal(0, 2, 100000)
print(np.mean(x)) # 평균
print(np.std(x)) # 표준편차
# 0.007768645296492016
# 1.9900835518846567
연산 함수
▶ sum()
- 배열 내부 연산을 지원하는 함수
- 배열의 랭크가 증가 할 때마다 새로운 축이 추가되어 차원이 증가됩니다.
▷ axis
- 배열의 랭크가 증가할 때마다 새로운 축이 추가되어 차원이 증가됩니다.
▶ 랭크 1의 연산.
test_array = np.arange(1, 11)
test_array.sum()
# 55
▶ 랭크 2의 연산.
print(np.arange(1, 13).reshape(3, 4).sum(axis = None))
# 78
print(np.arange(1, 13).reshape(3, 4).sum(axis = 0)) # 컬럼 별로 더한다.
# [15 18 21 24]
print(np.arange(1, 13).reshape(3, 4).sum(axis = 1)) # 로우 별로 더한다.
# [10 26 42]
▶ 랭크 3의 연산.
# 3차원 합
print(third_order_tensor.sum(axis = 1))
# [[15 18 21 24]
# [15 18 21 24]
# [15 18 21 24]]
print(third_order_tensor.sum(axis = 0))
# [[ 3 6 9 12]
# [15 18 21 24]
# [27 30 33 36]]
print(third_order_tensor.sum(axis = 2))
# [[10 26 42]
# [10 26 42]
# [10 26 42]]
# print(test_array)
print(test_array.mean(axis = 1))
print(test_array.std(axis = 0))
print(np.sqrt(test_array))
# [ 2.5 6.5 10.5]
# [3.26598632 3.26598632 3.26598632 3.26598632]
# [[1. 1.41421356 1.73205081 2. ]
# [2.23606798 2.44948974 2.64575131 2.82842712]
# [3.
연결 함수
- 두 객체 간의 결합을 지원하는 함수
▶ vastck 함수
- 배열을 수직으로 붙여 하나의 행렬을 생성합니다.
▶hstack 함수
- 배열을 수평으로 붙여 하나의 행렬을 생성합니다.
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
np.vstack((v1, v2))
# ([[1, 2, 3],
# [4, 5, 6]])
np.hstack((v1, v2))
# ([1, 2, 3, 4, 5, 6])
v1 = v1.reshape(-1, 1)
v2 = v2.reshape(-1, 1)
np.hstack((v1, v2))
# ([[1, 4],
# [2, 5],
# [3, 6]])
▶ concatenate 함수 (연결 함수)
- 축을 고려하여 두 개의 배열을 결합합니다.
- stack(스택) 계열의 함수와 달리 생성될 배열과 소스가 되는 배열의 차원이 같아야 합니다.
- 두 벡터를 결합한다면 해당 벡터를 2차원 배열꼴로 변환 한 후 행렬로 나타내야 합니다.
▷ 2랭크 연결
v1 = np.array([[1, 2, 3]])
v2 = np.array([[4, 5, 6]])
print(np.concatenate((v1, v2)))
# [[1 2 3]
# [4 5 6]]
▷ 2랭크 axis = 1 연결
v1 = np.array([[1, 2], [3, 4]])
v2 = np.array([[5], [6]])
print(np.concatenate((v1, v2), axis=1))
# [[1 2 5]
# [3 4 6]]
사칙연산 함수
- 넘파이는 파이썬과 동일하게 배열 간 사칙연산을 지원합니다.
- 행렬과 행렬, 벡터와 벡터 간 사칙연산이 가능합니다.
- 같은 배열의 구조일 때 요소별 연산(elemetn-wise operation)
- 요소별 연산 : 두 배열의 구조가 동일 할 경우 같은 인덱스 요소들끼리 연산합니다.
▷ 예문
x = np.arange(1, 7).reshape(2, 3)
print(x + x)
# [[ 2 4 6]
# [ 8 10 12]]
print(x - x)
# [[0 0 0]
# [0 0 0]]
print(x / x)
# [[1. 1. 1.]
# [1. 1. 1.]]
print(x ** x)
# [[ 1 4 27]
# [ 256 3125 46656]]
반응형
'Python' 카테고리의 다른 글
[Python] 파일 저장 (0) | 2022.09.27 |
---|---|
[Python] numpy 내적연산 (1) | 2022.09.24 |
[Python] Anaconda 가상환경 생성 (0) | 2022.09.21 |
[Python] CRAWLING - Element Access (0) | 2022.09.16 |
[Python] CRAWLING - BeautifulSoup (0) | 2022.09.13 |