일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 스택
- rnn
- 캐치카페신촌점 #캐치카페 #카페대관 #대학생 #진학사 #취준생
- 머신러닝
- 알고리즘
- GRU
- 큐
- 다이나믹 프로그래밍
- 최단 경로
- 선택정렬
- LSTM
- 삽입정렬
- 인공지능
- 그리디
- BFS
- 정렬
- pytorch
- Machine Learning
- AI
- 딥러닝
- 퀵정렬
- RESNET
- 선형대수
- 이진 탐색
- 계수정렬
- 재귀함수
- DFS
- Today
- Total
hyeonzzz's Tech Blog
[파머완 1장] 3. 넘파이 (NumPy) 본문
1. 파이썬 기반의 머신러닝과 생태계 이해 - 넘파이
1) 넘파이
머신러닝의 주요 알고리즘은 선형대수와 통계 등에 기반한다
넘파이
- 파이썬에서 선형대수 기반의 프로그램을 쉽게 만들 수 있도록 지원하는 대표적인 패키지
- 루프를 사용하지 않고 대량 데이터의 빠른 배열 연산을 가능하게 한다
- C/C++과 같은 저수준 언어 기반의 호환 API를 제공
- 수행 성능이 매우 중요한 부분은 C/C++ 기반의 코드로 작성하고 이를 넘파이에서 호출하는 방식으로 통합한다 (텐서플로)
하지만 2차원 형태의 행과 열 데이터를 처리하는 데에는 판다스가 더 편리하다!
2) 넘파이 ndarray 개요
array()
array() 함수 : 리스트와 같은 다양한 인자를 입력받아서 ndarray로 변환
shape 변수 : ndarray의 크기
array1 = np.array([1, 2, 3])
print('array1 type:', type(array1))
print('array1 array 형태:', array1.shape)
array1 type: <class 'numpy.ndarray'>
array1 array 형태: (3,) - 1차원 array로 3개의 데이터
array2 = np.array([[1, 2, 3],
[2, 3, 4]])
print('array2 type:', type(array2))
print('array2 array 형태:', array2.shape)
array2 type: <class 'numpy.ndarray'>
array2 array 형태: (2, 3) - 2차원 array로, 2개의 로우와 3개의 칼럼
array3 = np.array([[1, 2, 3]])
print('array3 type:', type(array3))
print('array3 array 형태:', array3.shape)
array3 type: <class 'numpy.ndarray'>
array3 array 형태: (1, 3) - 2차원 array로, 1개의 로우와 3개의 칼럼
데이터값으로는 서로 동일하나 차원이 달라서 오류가 발생하는 경우가 빈번하기 때문에 잘 알아두기!!
3) ndarray의 데이터 타입
리스트는 서로 다른 데이터 타입을 가질 수 있지만
ndarray내 데이터 타입은 같은 데이터 타입만 가능하다
list1 = [1, 2, 3]
print(type(list1))
array1 = np.array(list1)
print(type(array1))
print(array1, array1.dtype)
<class 'list'>
<class 'numpy.ndarray'>
[1 2 3] int64
하지만 만약 다른 데이터 유형이 섞여 있는 리스트를 ndarray로 변경하면 데이터 크기가 더 큰 데이터 타입으로 형 변환을 일괄 적용한다
list2 = [1, 2, 'test']
array2 = np.array(list2)
print(array2, array2.dtype)
list3 = [1, 2, 3.0]
array3 = np.array(list3)
print(array3, array3.dtype)
['1' '2' 'test'] <U21 - 숫자형 값 1, 2가 문자열 값 '1', '2'로 변환
[1. 2. 3.] float64 - int형 1, 2가 float형 1., 2.로 변환
astype()
메모리를 절약해야 할 때 보통 이용된다. 예를 들어 int형으로 충분한데 float형이 사용된 경우 이용한다
array_int = np.array([1, 2, 3])
array_float = array_int.astype('float64')
print(array_float, array_float.dtype)
[1. 2. 3.] float64
4) ndarray를 편리하게 생성하기
arange()
0부터 인자 값-1까지의 값을 ndarray의 데이터값으로 변환
sequence_array = np.arange(10)
print(sequence_array)
print(sequence_array.dtype, sequence_array.shape)
[0 1 2 3 4 5 6 7 8 9]
int64 (10,)
zeros()
모든 값을 0으로 채운 ndarray를 반환
ones()
모든 값을 1로 채운 ndarray를 반환
함수 인자로 dtype을 정해주지 않으면 default로 float64형의 데이터로 ndarray를 채운다
zero_array = np.zeros((3, 2), dtype='int32')
print(zero_array)
print(zero_array.dtype, zero_array.shape)
one_array = np.ones((3, 2))
print(one_array)
print(one_array.dtype, one_array.shape)
[[0 0]
[0 0]
[0 0]]
int32 (3, 2)
[[1. 1.]
[1. 1.]
[1. 1.]]
float64 (3, 2)
5) ndarray의 차원과 크기를 변경하는 reshape()
reshape()
ndarray를 특정 차원 및 크기로 변환한다
지정된 사이즈로 변경이 불가능하면 오류를 발생시킨다
array1 = np.arange(10)
print('array1:\n', array1)
array2 = array1.reshape(2,5)
print('array2:\n',array2)
array3 = array1.reshape(5,2)
print('array3:\n',array3)
array1:
[0 1 2 3 4 5 6 7 8 9]
array2:
[[0 1 2 3 4]
[5 6 7 8 9]]
array3:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
-1을 인자로 사용하면 원래 ndarray와 호환되는 새로운 shape로 변환해 준다
array1 = np.arange(10)
print(array1)
array2 = array1.reshape(-1,5)
print('array2 shape:',array2.shape)
array3 = array1.reshape(5,-1)
print('array3 shape:',array3.shape)
[0 1 2 3 4 5 6 7 8 9]
array2 shape: (2, 5) - 고정된 5개의 칼럼에 맞는 로우를 자동으로 생성
array3 shape: (5, 2) - 고정된 5개의 로우에 맞는 칼럼를 자동으로 생성
-1인자는 reshape(-1,1)과 같은 형태로 자주 사용된다
reshape(-1,1)
- 원본 ndarray가 어떤 형태라도 2차원
- 여러 개의 로우를 가지되 반드시 1개의 칼럼
여러개의 ndarray를 stack이나 concat으로 형태를 통일해 결합할 때 유용하게 사용된다!
array1 = np.arange(8)
array3d = array1.reshape((2,2,2))
print('array3d:\n',array3d.tolist())
# 3차원 ndarray를 2차원 ndarray로 변환
array5 = array3d.reshape(-1,1)
print('array5:\n',array5.tolist())
print('array5 shape:',array5.shape)
# 1차원 ndarray를 2차원 ndarray로 변환
array6 = array1.reshape(-1,1)
print('array6:\n',array6.tolist())
print('array6 shape:',array6.shape)
array3d:
[[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
array5:
[[0], [1], [2], [3], [4], [5], [6], [7]]
array5 shape: (8, 1)
array6:
[[0], [1], [2], [3], [4], [5], [6], [7]]
array6 shape: (8, 1)
6) ndarray의 데이터 세트 선택하기 - indexing
1] 단일 값 추출
1차원 ndarray에서 한 개의 데이터를 추출
# 1에서 부터 9 까지의 1차원 ndarray 생성
array1 = np.arange(start=1, stop=10)
print('array1:',array1)
# index는 0 부터 시작하므로 array1[2]는 3번째 index 위치의 데이터 값을 의미
value = array1[2]
print('value:',value)
print(type(value))
array1: [1 2 3 4 5 6 7 8 9]
value: 3
<class 'numpy.int64'>
다차원의 ndarray에서 단일 값을 추출
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print(array2d)
print('(row=0,col=0) index 가리키는 값:', array2d[0,0] )
print('(row=0,col=1) index 가리키는 값:', array2d[0,1] )
print('(row=1,col=0) index 가리키는 값:', array2d[1,0] )
print('(row=2,col=2) index 가리키는 값:', array2d[2,2] )
[[1 2 3]
[4 5 6]
[7 8 9]]
(row=0,col=0) index 가리키는 값: 1
(row=0,col=1) index 가리키는 값: 2
(row=1,col=0) index 가리키는 값: 4
(row=2,col=2) index 가리키는 값: 9
7) slicing
시작 인덱스 : 종료 인덱스
array1 = np.arange(start=1, stop=10)
array3 = array1[0:3]
print(array3)
print(type(array3))
[1 2 3]
<class 'numpy.ndarray'>
2차원 ndarray에서 slicing
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print('array2d:\n',array2d)
print('array2d[0:2, 0:2] \n', array2d[0:2, 0:2])
print('array2d[1:3, 0:3] \n', array2d[1:3, 0:3])
print('array2d[1:3, :] \n', array2d[1:3, :])
print('array2d[:, :] \n', array2d[:, :])
print('array2d[:2, 1:] \n', array2d[:2, 1:])
print('array2d[:2, 0] \n', array2d[:2, 0])
print(array2d[0])
print(array2d[1])
print('array2d[0] shape:', array2d[0].shape, 'array2d[1] shape:', array2d[1].shape )
[1 2 3] - axis 0의 첫번째 로우 ndarray 반환
[4 5 6] - axis 0의 두번째 로우 ndarray 반환
array2d[0] shape: (3,) array2d[1] shape: (3,) - 반환되는 ndarray는 1차원
8) Fancy Indexing
리스트나 ndarray로 인덱스 집합을 지정하는 방식
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
array3 = array2d[[0,1], 2]
print('array2d[[0,1], 2] => ',array3.tolist())
array4 = array2d[[0,1], 0:2]
print('array2d[[0,1], 0:2] => ',array4.tolist())
array5 = array2d[[0,1]]
print('array2d[[0,1]] => ',array5.tolist())
9) Boolean Indexing
[ ] 내에 조건문을 그대로 기재하는 방식
array1d = np.arange(start=1, stop=10)
# [ ] 안에 array1d > 5 Boolean indexing을 적용
array3 = array1d[array1d > 5]
print('array1d > 5 불린 인덱싱 결과 값 :', array3)
array1d > 5 불린 인덱싱 결과 값 : [6 7 8 9]
직접 False, True로 이루어진 ndarray를 만들어 해당 위치의 데이터를 반환하게 만들 수 있다!!
10) 행렬의 정렬 - sort()와 argsort()
np.sort(), ndarray.sort()
np.sort() - 원래 행렬은 그대로 유지한 채 원 행렬의 정렬된 행렬을 반환
ndarray.sort() - 원 행렬 자체를 정렬. 반환 값은 None
org_array = np.array([ 3, 1, 9, 5])
print('원본 행렬:', org_array)
# np.sort( )로 정렬
sort_array1 = np.sort(org_array)
print ('np.sort( ) 호출 후 반환된 정렬 행렬:', sort_array1)
print('np.sort( ) 호출 후 원본 행렬:', org_array)
# ndarray.sort( )로 정렬
sort_array2 = org_array.sort()
print('org_array.sort( ) 호출 후 반환된 행렬:', sort_array2)
print('org_array.sort( ) 호출 후 원본 행렬:', org_array)
원본 행렬: [3 1 9 5]
np.sort( ) 호출 후 반환된 정렬 행렬: [1 3 5 9]
np.sort( ) 호출 후 원본 행렬: [3 1 9 5]
org_array.sort( ) 호출 후 반환된 행렬: None
org_array.sort( ) 호출 후 원본 행렬: [1 3 5 9]
내림차순으로 정렬 - np.sort()[::-1]
axis 축별 정렬
array2d = np.array([[8, 12],
[7, 1 ]])
sort_array2d_axis0 = np.sort(array2d, axis=0)
print('로우 방향으로 정렬:\n', sort_array2d_axis0)
sort_array2d_axis1 = np.sort(array2d, axis=1)
print('컬럼 방향으로 정렬:\n', sort_array2d_axis1)
로우 방향으로 정렬:
[[ 7 1]
[ 8 12]]
컬럼 방향으로 정렬:
[[ 8 12]
[ 1 7]]
11) 정렬된 행렬의 인덱스를 반환하기
np.argsort()
정렬 행렬의 원본 행렬 인덱스를 ndarray 형으로 반환한다
org_array = np.array([ 3, 1, 9, 5])
sort_indices = np.argsort(org_array)
print(type(sort_indices))
print('행렬 정렬 시 원본 행렬의 인덱스:', sort_indices)
<class 'numpy.ndarray'>
행렬 정렬 시 원본 행렬의 인덱스: [1 0 3 2]
내림차순으로 정렬 - np.argsort()[::-1]
넘파이의 데이터 추출에서 argsort()의 활용
넘파이는 메타 데이터를 가질 수 없기 때문에 별도의 ndarray를 가져야 한다. 이때 argsort()는 유용하게 쓰인다
import numpy as np
name_array = np.array(['John', 'Mike', 'Sarah', 'Kate', 'Samuel'])
score_array= np.array([78, 95, 84, 98, 88])
sort_indices_asc = np.argsort(score_array)
print('성적 오름차순 정렬 시 score_array의 인덱스:', sort_indices_asc)
print('성적 오름차순으로 name_array의 이름 출력:', name_array[sort_indices_asc])
성적 오름차순 정렬 시 score_array의 인덱스: [0 2 4 1 3]
성적 오름차순으로 name_array의 이름 출력: ['John' 'Sarah' 'Samuel' 'Mike' 'Kate']
12) 선형대수 연산 - 행렬 내적과 전치 행렬 구하기
행렬 내적(행렬 곱)
np.dot()
A = np.array([[1, 2, 3],
[4, 5, 6]])
B = np.array([[7, 8],
[9, 10],
[11, 12]])
dot_product = np.dot(A, B)
print('행렬 내적 결과:\n', dot_product)
행렬 내적 결과:
[[ 58 64]
[139 154]]
전치 행렬
전치 행렬 : 원 행렬에서 행과 열의 위치를 교환한 행렬
transpose()
A = np.array([[1, 2],
[3, 4]])
transpose_mat = np.transpose(A)
print('A의 전치 행렬:\n', transpose_mat)
A의 전치 행렬:
[[1 3]
[2 4]]
'Machine Learning' 카테고리의 다른 글
[파머완 2장] 4. Model Selection 모듈 소개 (1) | 2024.01.09 |
---|---|
[파머완 2장] 3. 사이킷런의 기반 프레임워크 익히기 (0) | 2024.01.04 |
[파머완 2장] 1. 사이킷런 소개와 특징 2. 붓꽃 품종 예측하기 (1) | 2024.01.04 |
[파머완 1장] 4. 판다스 (Pandas) (1) | 2024.01.04 |
[파머완 1장] 1. 머신러닝의 개념 (0) | 2024.01.02 |