해당 포스트는 책 “파이썬 머신러닝 완벽 가이드”의 내용을 학습하여 정리한 글입니다.
Ch01. 파이썬 기반의 머신러닝과 생태계 이해
v03. 넘파이
3.1 넘파이 ndarray 개요
import numpy as np
넘파이의 기반 데이터 타입은 ndarray이다.
ndarray.shape : array의 크기(행과 열의 수) 확인
array1 = np.array([1,2,3])
print('array1 type:', type(array1))
print('array1 array 형태:', array1.shape)
array1 type: <class 'numpy.ndarray'>
array1 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)
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)
ndarray.ndim : array의 차원 확인
print('array1: {:0}차원, array2: {:1}차원, array3: {:2}차원'.format(array1.ndim,
array2.ndim,
array3.ndim))
array1: 1차원, array2: 2차원, array3: 2차원
3.2 ndarray의 데이터 타입
dtype : 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] int32
int형과 string형이 섞여 있는 경우
list2 = [1,2, 'test']
array2 = np.array(list2)
print(array2, array2.dtype)
['1' '2' 'test'] <U11
int형과 float형이 섞여 있는 경우
list3 = [1,2, 3.0]
array3 = np.array(list3)
print(array3, array3.dtype)
[1. 2. 3.] float64
astype() : ndarray 내 데이터값의 타입 변경
- int32형 \(\rightarrow\) float64으로 변환
array_int = np.array([1,2,3])
print("array_int dtype : ", array_int.dtype)
array_float = array_int.astype('float64')
print(array_float, array_float.dtype)
array_int dtype : int32
[1. 2. 3.] float64
- float64 \(\rightarrow\) int32로 변환 (소숫점 아래 데이터 없는 경우)
array_int1 = array_float.astype('int32')
print(array_int1, array_int1.dtype)
[1 2 3] int32
- float64 \(\rightarrow\) int32로 변환 (소숫점 아래 데이터 있는 경우)
array_float1 = np.array([1.1, 2.1, 3.1])
print(array_float1, array_float1.dtype)
array_int2 = array_float1.astype('int32')
print(array_int2, array_int2.dtype)
[1.1 2.1 3.1] float64
[1 2 3] int32
3.3 ndarray를 편리하게 생성하기 - arange, zeros, ones
3.3.1 arange()
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]
int32 (10,)
3.3.2 zeros()
zero_array = np.zeros((3,2), dtype='int32')
print(zero_array)
print(zero_array.dtype, zero_array.shape)
[[0 0]
[0 0]
[0 0]]
int32 (3, 2)
3.3.3 ones()
one_array = np.ones((3,2))
print(one_array)
print(one_array.dtype, one_array.shape)
[[1. 1.]
[1. 1.]
[1. 1.]]
float64 (3, 2)
3.4 ndarray의 차원과 크기를 변경하는 reshape()
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]]
# array1.reshape(4,3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-23-a40469ec5825> in <module>
----> 1 array1.reshape(4,3)
ValueError: cannot reshape array of size 10 into shape (4,3)
reshape()에 -1을 인자로 사용
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)
array3 shape: (5, 2)
array1 = np.arange(10)
# array4 = array1.reshape(-1, 4)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-26-474c3d9b15cb> in <module>
1 array1 = np.arange(10)
----> 2 array4 = array1.reshape(-1, 4)
ValueError: cannot reshape array of size 10 into shape (4)
reshape(-1, 1)
- 원본 ndarray가 어떤 형태라도 2차원이고, 여러 개의 로우를 가지되 반드시 1개의 컬럼을 가진 ndarray로 변환됨을 보장
tolist()
- ndarray를 list 자료형으로 변환
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 shap: ', 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 shap: (8, 1)
array6:
[[0], [1], [2], [3], [4], [5], [6], [7]]
array6 shape: (8, 1)
3.5 넘파이의 ndarray의 데이터 세트 선택하기 - 인덱싱(Indexing)
3.5.1 단일 값 추출 (특정한 데이터만 추출)
# 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.int32'>
[-1]는 맨 뒤의 데이터값 의미
print('맨 뒤의 값:', array1[-1], ' 맨 뒤에서 두 번째 값:', array1[-2])
맨 뒤의 값: 9 맨 뒤에서 두 번째 값: 8
- 단일 인덱스 이용 ndarray 내의 데이터값 수정
array1[0] = 9
array1[8] = 0
print('array1:', array1)
array1: [9 2 3 4 5 6 7 8 0]
다차원 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
axis
axis=0: 로우 방향의 축 의미axis=1: 컬럼 방향의 축 의미- [row=0, col=1] \(\Rightarrow\) [axis 0=0, axis 1=1]
- 2차원 \(\Rightarrow\) axis 0, axis 1
- 3차원 \(\Rightarrow\) axis 0, axis 1, axis 2
- 축 기반의 연산에서 axis가 생략 \(\Rightarrow\) axis 0을 의미
3.5.2 슬라이싱
array1 = np.arange(start=1, stop=10)
array3 = array1[0:3]
print(array3)
print(type(array3))
[1 2 3]
<class 'numpy.ndarray'>
array1 = np.arange(start=1, stop=10)
array4 = array1[:3]
print(array4)
array5 = array1[3:]
print(array5)
array6 = array1[:]
print(array6)
[1 2 3]
[4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9]
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])
array2d:
[[1 2 3]
[4 5 6]
[7 8 9]]
array2d[0:2, 0:2]
[[1 2]
[4 5]]
array2d[1:3, 0:3]
[[4 5 6]
[7 8 9]]
array2d[1:3, :]
[[4 5 6]
[7 8 9]]
array2d[:, :]
[[1 2 3]
[4 5 6]
[7 8 9]]
array2d[:2, 1:]
[[2 3]
[5 6]]
array2d[:2, 0]
[1 4]
print(array2d[0])
print(array2d[1])
print('array2d[0] shape : ', array2d[0].shape, '\narray2d[1] shape : ', array2d[1].shape)
[1 2 3]
[4 5 6]
array2d[0] shape : (3,)
array2d[1] shape : (3,)
3.5.3 팬시 인덱싱
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3, 3)
array3 = array2d[[0, 1], 2] # (0, 2), (1, 2)
print('array2d[[0, 1], 2] => ', array3.tolist())
array4 = array2d[[0, 1], 0:2] # ( (0,0), (0,1) ), ( (1,0), (1,1) )
print('array2d[[0, 1], 0:2] => ', array4.tolist())
array5 = array2d[[0, 1]] # ( (0, :), (1, :) )
print('array2d[[0, 1]] => ', array5.tolist())
array2d[[0, 1], 2] => [3, 6]
array2d[[0, 1], 0:2] => [[1, 2], [4, 5]]
array2d[[0, 1]] => [[1, 2, 3], [4, 5, 6]]
3.5.4 불린 인덱싱
array1 = np.arange(start=1, stop=10)
# [] 안에 array1d > 5 Boolean indexing을 적용
array3 = array1d[array1d > 5]
print('array1d > 5 불린 인덱싱 결과 값 : ', array3)
array1d > 5 불린 인덱싱 결과 값 : [6 7 8 9]
array1d > 5
array([False, False, False, False, False, True, True, True, True])
type(array1d > 5)
numpy.ndarray
boolean_indexes = np.array([False, False, False, False, False, True, True, True, True])
array3 = array1d[boolean_indexes]
print('불린 인덱스로 필터링 결과 : ', array3)
불린 인덱스로 필터링 결과 : [6 7 8 9]
indexes = np.array([5,6,7,8])
array4 = array1d[indexes]
print('일반 인덱스로 필터링 결과 : ', array4)
일반 인덱스로 필터링 결과 : [6 7 8 9]
3.6 행렬의 정렬 - sort()와 argsort()
넘파이에서의 행렬을 정렬하는 대표적인 방법
np.sort()ndarray.sort()
argsort() : 정렬된 행렬의 인덱스 반환
3.6.1 행렬 정렬
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('ndarray.sort() 호출 후 반환된 행렬 : ', sort_array2)
print('ndarray.sort() 호출 후 원본 행렬 : ', org_array)
원본 행렬 : [3 1 9 5]
np.sort() 호출 후 반환된 정렬 행렬 : [1 3 5 9]
np.sort() 호출 후 원본 행렬 : [3 1 9 5]
ndarray.sort() 호출 후 반환된 행렬 : None
ndarray.sort() 호출 후 원본 행렬 : [1 3 5 9]
[::-1] : 내림차순 정렬
sort_array1_desc = np.sort(org_array)[::-1]
print('내림차순으로 정렬 : ', sort_array1_desc)
내림차순으로 정렬 : [9 5 3 1]
행렬이 2차원 이상일 경우에 axis 축 값 설정을 통해 로우 방향, 컬럼 방향으로 정렬 수행
axis=0: 로우 방향axis=1: 컬럼 방향
array2d = np.array([[8, 12],
[7, 1]])
print(array2d)
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)
[[ 8 12]
[ 7 1]]
로우 방향으로 정렬 :
[[ 7 1]
[ 8 12]]
컬럼 방향으로 정렬 :
[[ 8 12]
[ 1 7]]
3.6.2 정렬된 행렬의 인덱스를 반환하기
원본 행렬이 정렬되었을 때 기존 원본 행렬의 원소에 대한 인덱스를 필요로 할 때 np.argsort()를 이용.
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]
내림차순 정렬 ([::-1])
org_array = np.array([3, 1, 9, 5])
sort_indices = np.argsort(org_array)[::-1]
print(type(sort_indices))
print('행렬 내림차순 정렬 시 원본 행렬의 인덱스 : ', sort_indices)
<class 'numpy.ndarray'>
행렬 내림차순 정렬 시 원본 행렬의 인덱스 : [2 3 0 1]
3.7 선형대수 연산 - 행렬 내적과 전치 행렬 구하기
3.7.1 행렬 내적(행렬 곱)
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]]
3.7.2 전치 행렬
np.transpose()
A = np.array([[1, 2],
[3, 4]])
transpose_mat = np.transpose(A)
print('A의 전치 행렬 : \n', transpose_mat)
A의 전치 행렬 :
[[1 3]
[2 4]]
댓글남기기