철솜_STUDY
파이썬 머신러닝 완벽 가이드 _ CH.1_(2) 본문
CH.1.4 _ NumPy
머신러닝의 알고리즘은 선형대수와 통계에 기반한다. NumPy는 Numerical Python를 의미하며, 루프를 사용하지 않고도 대량 데이터의 배열 연산을 수행한다. 연산 속도의 측면에서는 이점이 있으나, 파이썬 언어 자체의 수행 성능에 제약이 있으므로 C/C++과의 호환 API를 제공한다.
그러나 NumPy는 Pandas와 달리 같은 데이터 타입만 배열 데이터로 관리할 수 있다는 단점이 있다.
1. ndarray 란?
- n차원의 배열 객체 - C의 array와 유사하다고 보면 된다.
- np.array(대상 list, data type) - 기존의 list를 ndarray 형태로 바꿔주는 함수
- type(ndarray) - 타입을 알려주는 함수
- ndarray.shape - ndarray의 구조를 튜플(tuple) 형태로 알려주는 메서드
- ndarray.ndim - ndarray의 차원을 보여주는 메서드
*tuple - python의 자료형. ( )를 이용해 만든다.
import numpy as np
a = [1, 2, 3, 4, 5]
array1 = np.array(a)
array2 = np.array(a, float)
array3 = np.array([[1, 2, 3], [2, 3, 4]])
array4 = np.array([[1, 2, 3]])
print("array1 type: ", type(array1))
print("array1 array 형태 : ", array1.shape)
print("array1 type: ", type(array2))
print("array3 array 형태 : ", array3.shape)
print("array4 array 형태 : ", array4.shape)
print("array1 : {0}차원, array3 : {1}차원, array4 : {2}차원".format(array1.ndim, array3.ndim, array4.ndim))
2. ndarray의 data type
ndarray는 숫자형, 문자열, 불 값 모두 올 수 있다.
*숫자형 - signed int형, unsigned int형, float형, complex 타입
list의 경우 서로 다른 데이터 타입을 가질 수 있다. 그러나 numPy는 불가능하기 때문에 만약 list 내에 서로 다른 데이터 타입이 존재한다면, 데이터의 크기가 더 큰 데이터 타입으로 형 변환을 적용한다.
- ndarray.dtype - ndarray 내부 원소의 데이터 타입을 알려주는 메서드
- ndarray.astype - ndarray 내부 원소의 데이터 타입을 변경하는 메서드
list2 = [1, 2, 'test']
array5 = np.array(list2)
print(array5, array5.dtype)
list3 = [1, 2, 3.0]
array6 = np.array(list3)
print(array6, array6.dtype)
3. 특수한 ndarray 생성하기
arange() / zeros() / ones()를 이용해 특수한 ndarray를 쉽게 생성할 수 있다.
이런 특수한 ndarray는 테스트용 데이터를 만들거나, 대규모의 데이터를 일괄적으로 초기화해야 할 경우 사용된다.
- arange(start=0, stop=, step=1) - 0부터 함수 인자 값 직전까지의 값을 ndarray의 원소로 변환하는 메서드이다. 각 숫자는 해당 옵션의 default 값.
- zeros(shape, dtype='float64') - 튜플 형태의 shape 값을 갖고 0으로 채워진 ndarray를 반환하는 메서드로, dtype의 default 는 float64.
- ones(shape, dtype='float64') - 튜플 형태의 shape을 갖고 1로 채워진 ndarray를 반환하는 메서드로, dtype의 default는 float64.
import numpy as np
npp=np.arange(0, 10, step=0.5)
print(npp)
zero_array = np.zeros((3,2))
zero_array2 = np.zeros((3,2), dtype='int32')
print(zero_array)
print(zero_array2)
ones_array = np.ones((3,2))
ones_array2 = np.ones((3,2), dtype='int32')
print(ones_array)
print(ones_array2)
4. reshape(row = , col = ) _ ndarray의 차원과 크기를 변경하는
이미 존재하는 ndarray의 차원이나 크기를 바꾸고 싶을 때 사용하는 메서드이다.
다만 지정된 사이즈로 변경이 가능해야 한다. 예를 들어 3*4 구조의 ndarray를 5*3 구조로 바꿀 수 없는 것이다.
row나 col에 -1을 넣을 경우, 고정돼 있는 다른 옵션의 값에 들어맞는 적절한 새로운 ndarray를 생성하라는 의미이다.
*reshape(-1,1) _ 원본 ndarray를 n*1의 형태로 변환해준다.
여러 개의 ndarray를 stack이나 concat으로 결합할 때 ndarray의 형태를 통일해줄 때 유용하다.
*tolist() _ array를 list 자료형으로 변경해주는 메서드
array1 = np.arange(10)
print(array1)
array2 = array1.reshape(-1, 5)
# array1은 1*10 이지만, array2는 2*5가 된다
array1 = np.arange(8)
array3d = array1.reshape((2,2,2)) #1차원을 3차원으로 변경
print("array3d: \n", array3d.tolist())
array2d = array3d.reshape((-1,1)) #3차원을 2차원으로 변경
print("array2d: \n", array2d.tolist())
array2d2 = array1.reshape((-1,1)) #1차원을 2차원으로 변경
print("array2d2: \n", array2d2.tolist())
5. Indexing _ ndarray의 데이터 선택하기
NumPy에서 데이터를 선택하는 방법은 크게 4종류이다.
index를 이용해 특정한 위치의 단일 값만 추출하는 방법, : 를 이용해연속된 인덱스 상의 ndarray를 추출하는 방법인 Slicing, 일정한 인덱싱 집합을 리스트나 ndarray 형태로 지정해 ndarray를 반환하는 Fancy Indexing, TRUE FALSE를 이용해 특정 조건에 해당하는 ndarray를 반환하는 Boolean Indexing 이 있다.
*axis = 0, axis =1 _ row 와 column을 NumPy에서 나타내는 방법.
차원이 늘어날 수록 axis = 2, 3, 4.. 처럼 숫자를 늘려 표현하게 된다. default 값은 0이다.
import numpy as np
array1 = np.arange(1, 10)
# index와 -를 이용해 원소를 추출하는 예시
print("맨 뒤에 있는 값 : ", array1[-1])
print("맨 뒤에서 두 번째 값 : ", array[-2])
# 다차원 ndarray에서 원소를 추출하는 예시
array1_2 = array1.reshape(3,3)
print(array1_2)
print("(row=0, col=0) index가 가리키는 값 : ", array1_2[0,0])
Slicing은 stop index의 직전 index까지의 값을 반환한다. 또한 1차원과 n차원에서도 적용 가능하다.
예를 들어 2차원 ndarray에서 첫번째 []만을 채운다면 특정한 row만을 추출할 수 있다.
특정한 col을 추출하고 싶다면 [:, n]이라는 형태의 slicing이 가능하다.
*slicing에도 default 값이 있다.
strat와 stop을 생략하면 자동으로 해당 ndarray 시작과 끝을 default 값으로 가져온다.
#slicing 예시 _ 1차원 (n차원에서도 적용 가능하다)
array2 = np.arange(1, 10)
array3 = array3[0:3]
print(array3)
print(array2[:3])
print(array2[1:6])
print(array2[:])
array9 = np.arange(1, 10)
array9 = array9.reshape(3,3)
print(array9)
print(array9[1])
print(array9[:, 1])
Fancy Indexing은 다음과 같다.
ndarray를 생성한 후 특정 인덱스를 slicing한 결과를 또다른 ndarray로 저장한다.
array1d = np.arange(1, 10)
array2d = array1d.reshape(3,3)
array3 = array2d[[0,1],2]
print("array2d[[0,1],2] => ", array3.tolist())
Boolean Indexing은 조건 필터링과 검색을 동시에 할 수 있는 방법이다.
array3 = np.arange(1, 10)
array4= array3[array3 > 5]
array3 > 5
array3[array3>5]
print("array4 => ", array4)
6. sort() & argsort() _ 행렬의 정렬
#sort()
np.sort(ndarray) 와 ndarray.sort는 서로 다르다.
np.sort는 NumPy에서 sort 함수를 호출하는 형식이고, ndarray는 행렬 자체에서 sort를 호출하는 메서드 방식이다.
이 둘의 차이점을 간단하게 설명하면
np.sort(ndarray)는 원본 ndarray 행렬의 형태를 바꾸지 않고, 새로운 행렬을 생성하게 된다.
ndarray.sort() 는 원본 ndarray의 행렬의 형태를 바꾸고, 새로운 행렬을 반환하지 않는다.
이 둘 모두 기본적으로 오름차순으로 행렬 내 원소를 정렬한다.
만약 내림차순으로 정렬하고 싶다면 [::-1]라는 옵션을 사용할 수 있다.
만약 n차원 행렬이라면 axis 방향을 설정해 정렬할 수 있다.
import numpy as np
org_array = np.array([3, 1, 5, 8, 2])
print(org_array)
sort1 = np.sort(org_array)
print("np.sort(ndarray) 후의 정렬 : ", sort1)
print("np.sort() 후의 내림차순 정렬 : ", np.sort(org_array)[::-1] )
print("np.sort(ndarray) 후의 원본 정렬 : ", org_array)
sort2 = org_array.sort()
print("ndarray.sort() 후의 정렬 : ", sort2)
print("ndarray.sort() 후의 원본 정렬 : ", org_array)
array2d2 = np.array([[8,12],[7,1]])
sort_array2d2r = np.sort(array2d2, axis=0)
print("row 방향으로 정렬 : \n", sort_array2d2r)
sort_array2d2c = np.sort(array2d2, axis=1)
print("col 방향으로 정렬 : \n", sort_array2d2c)
#argsort(ndarray)
argsort() 는 원본 행렬 원소의 index를 정렬해 나열하는 것이다.
이 함수는 NumPy에서 활용도가 높다. array 속 원소의 data type가 동일해야 하기 때문에 여러 정보를 표현하기 위해서는 여러 개의 ndarray가 필요하다. 이 때 유용하게 사용되는 것이 이 argsort()이다.
import numpy as np
name_array = np.array(['John', 'Mike', 'Sarah', 'Kate', 'Samuel'])
score_Array = np.array([78, 89, 29, 70, 68])
sort_index = np.argsort(score_Array)
print('오름차순 정렬 시 성적 array의 index => \n', sort_index)
print('오름차순 정렬 시 성적 array의 index => \n', score_Array[sort_index])
print('오름차순 정렬 시 이름 array의 형태 => \n', name_array[sort_index])
7. 행렬 내적 & 전치 행렬 _ 선형대수 연산
행렬의 내적 = 행렬의 곱. np.dot(ndarray1, ndarray2)을 이용한다.
전치 행렬은 np.transpose(ndarray)를 이용한다.
'Self-Taught > Machine Learning' 카테고리의 다른 글
파이썬 머신러닝 완벽 가이드 _ CH.4.1~4.6 (1) | 2024.11.02 |
---|---|
파이썬 머신 러닝 완벽 가이드 _ CH.3 (2) | 2024.10.12 |
파이썬 머신러닝 완벽가이드 _ CH.2_(1) (3) | 2024.10.05 |
파이썬 머신러닝 완벽 가이드 _ CH.1_(3) (1) | 2024.09.28 |
파이썬 머신러닝 완벽 가이드 _ CH.1_(1) (1) | 2024.09.28 |