[Machine Learning] 01. 넘파이

Nina·2021년 1월 24일
0
post-thumbnail

「권철민(2020).파이썬 머신러닝 완벽가이드(개정판).위키북스」 책으로 공부한 뒤 정리한 내용.

1. NumPy

머신러닝의 주요 알고리즘은 선형대수와 통계 등에 기반하는데, 넘파이(Numerical Python)는 파이썬에서 선형대수 기반의 프로그램을 쉽게 만들 수 있도록 지원하는 대표적인 패키지이다. 넘파이를 이용하면 대량 데이터의 배열 연산을 루프 없이도 빠르게 실행할 수 있다.

2. ndarray의 형태

먼저 넘파이 모듈을 임포트한다.

import numpy as np

array()함수는 리스트와 같은 인자를 입력받아 넘파이의 기반 데이터 타입인 ndarray로 변환한다.

>>> array1 = np.array([1,2,3])
>>> array2 = np.array([[1,2,3],[4,5,6]])
>>> array3 = np.array([[1,2,3]])
>>> type(array1)
<class 'numpy.ndarray'>
>>> array1.shape
(3,)
>>> array2.shape
(2, 3)
>>> array3.shape
(1, 3)

ndarray.shape는 ndarray의 차원과 크기를 튜플의 형태로 반환한다. array1의 shape는 (3,)으로, 이는 array1이 1차원 array이며 3개의 데이터를 갖고있음을 의미한다. 한편 array2와 array3는 각각 2개, 1개의 로우와 3개의 컬럼을 가진 2차원 array이다. array의 차원은 ndarray.ndim으로 확인할 수 있다.

>>> array1.ndim
1
>>> array2.ndim
2
>>> array3.ndim
2

3. ndarray의 데이터 타입

ndarray 내 데이터값은 숫자, 문자열, 불리언 값이 모두 가능하지만, 하나의 ndarray 내 데이터 타입은 모두 동일해야한다. 데이터 타입은 array.dtype으로 확인 가능하다.

>>> array1 = np.array([1,2,3])
>>> array1.dtype
dtype('int64')

만약 하나의 ndarray 안에 여러개의 데이터 유형이 섞여있는 경우 데이터 크기가 더 큰 데이터 타입으로 일괄 적용한다.

>>> array2 = np.array([1,2,3.0])
>>> array3 = np.array([1,2,'안녕'])
>>> array2.dtype
dtype('float64')
>>> array3.dtype
dtype('<U21')

astype() 메소드를 이용해 데이터 타입을 변경할 수 있다.

>>> array1.astype('<U11')
array(['1', '2', '3'], dtype='<U11')
>>> array1.astype('float64')
array([1., 2., 3.])

4. arange, zeros, ones

(1) arange

start(default:0)부터 stop 범위 내의 값들을 1차원 ndarray의 데이터값으로 변환해준다.

>>> array1 = np.arange(10)
>>> array2 = np.arange(start=10, stop=20)
>>> array1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> array2
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

(2) zeros, ones

zeros()와 ones()는 각각 0, 1로 채워진 ndarray를 반환한다. shape와 데이터 타입을 지정할 수 있으며, 디폴트 데이터 타입은 float64이다.

>>> array_zero = np.zeros((2,2), dtype='int32')
>>> array_one = np.ones((3,3), dtype='<U21')
>>> array_zero
array([[0, 0],
       [0, 0]], dtype=int32)
>>> array_one
array([['1', '1', '1'],
       ['1', '1', '1'],
       ['1', '1', '1']], dtype='<U21')

5. ndarray의 차원 및 크기 변경

reshape() 메소드를 사용해 ndarray의 차원과 크기를 변경할 수 있다.

>>> array1 = np.arange(10)
>>> array2 = array1.reshape(2,5)
>>> array3 = array1.reshape(5,2)
>>> array2
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
>>> array3
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])

만약 reshape가 불가능하다면(zb. array = array1.reshape(3,3)) 오류가 발생한다. -1을 입력할 경우, 기존 ndarray와 호환되는 shape로 자동적으로 변환한다.

>>> array4 = array1.reshape(-1,2)
>>> array4
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7],
       [8, 9]])

6. ndarray 인덱싱

ndarray의 인덱싱은 파이썬 리스트의 그것과 유사하다. 주의해야할 점은, axis0(row), axis1(column)순으로 작성해야한다는 것이다.

>>> array = np.arange(start=1,stop=10)
>>> array = array.reshape(3,3)
>>> array[0,0]
1
>>> array[0,1]
2
>>> array[1,0]
4
>>> array[2,0]
7
>>> array[0:2,0:2]
array([[1, 2],
       [4, 5]])
>>> array[1:3,1:3]
array([[5, 6],
       [8, 9]])

넘파이를 이용하면 boolean indexing을 할 수 있는데, 이를 통해 조건 필터링과 검색을 동시에 수행할 수 있다. 따라서 for loop를 이용하지 않아도 리스트에서 조건을 충족시키는 데이터를 찾을 수 있기 때문에 효율적이다.

>>> array1 = np.arange(100)
>>> array2 = array1[array1 % 3 == 2]
>>> array2
array([ 2,  5,  8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50,
       53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98])

불리언 값을 반환하면 이렇다.

>>> array1 % 3 == 2
array([False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False, False,  True, False, False,  True, False, False,  True,
       False])

7. 행렬의 정렬

(1) sort()

넘파이의 행렬 정렬에는 np.sort()와 ndarray.sort()가 있다. 전자의 경우 넘파이에서 sort()를 호출하는 방식이며, 따라서 원 행렬은 그대로 유지한채 새로운 정렬된 행렬을 반환한다. 반면 후자의 경우 행렬 자체에서 sort()를 호출하는 방식으로, 원 행렬이 정렬되며 새로운 행렬로는 None을 반환한다.
np.sort()

>>> array1 = np.array([6,2,5,3,7])
>>> array2 = np.sort(array1)
>>> array2
array([2, 3, 5, 6, 7])
>>> array1
array([6, 2, 5, 3, 7])

ndarray.sort()

>>> array3 = array1.sort()
>>> array1
array([2, 3, 5, 6, 7])
>>> array3
>>>

(2) 2차원 이상의 행렬

행렬이 2차원 이상인 경우 axis=0 또는 axis=1로 축 값을 설정함으로써 정렬 기준을 정할 수 있다.

>>> array1 = np.array([[7,3,8],[6,4,2],[5,4,1]])
>>> array2 = np.sort(array1, axis=0)
>>> array3 = np.sort(array1, axis=1)
>>> array1
array([[7, 3, 8],
       [6, 4, 2],
       [5, 4, 1]])
>>> array2
array([[5, 3, 1],
       [6, 4, 2],
       [7, 4, 8]])
>>> array3
array([[3, 7, 8],
       [2, 4, 6],
       [1, 4, 5]])

(3) argsort()

argsort()를 이용해 정렬된 행렬의 인덱스를 반환할 수 있다.

>>> name_array = np.array(['Nina','ChaeYeong','Sam','Hannah','Jonas','Nora'])
>>> score_array = np.array([94,92,91,79,83,95])
>>> sorted_score = np.argsort(score_array)[::-1]
>>> sorted_score
array([5, 0, 1, 2, 4, 3])
>>> name_array[sorted_score]
array(['Nora', 'Nina', 'ChaeYeong', 'Sam', 'Jonas', 'Hannah'], dtype='<U9')

학생 이름과 점수를 담고있는 행렬을 각각 만든 뒤, 점수를 내림차순으로 정렬한 인덱스를 반환한다. 이를 이용해 학생 이름 행렬을 정렬하면 점수가 높은 학생 순서대로 정렬한 행렬을 출력할 수 있다.

8. 선형대수 연산

(1) 행렬 내적

dot()을 이용해 행렬의 곱을 아주 쉽게 구할 수 있다.

>>> array1 = np.array([[5,2,6],[1,7,3]])
>>> array2 = np.array([[6,2],[4,2],[3,7]])
>>> new_array = np.dot(array1,array2)
>>> new_array
array([[56, 56],
       [43, 37]])

(2) 전치 행렬

원 행렬에서 행과 열의 위치를 교환한 원소로 구성된 행렬을 전치 행렬이라고 한다. transpose()를 이용해 전치 행렬을 구할 수 있다.

>>> array1 = np.array([[4,2],[1,8]])
>>> array2 = np.transpose(array1)
>>> array2
array([[4, 1],
       [2, 8]])
profile
https://dev.to/ninahwang

0개의 댓글