해당 포스트는 책 “파이썬 머신러닝 완벽 가이드”의 내용을 학습하여 정리한 글입니다.
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]]
댓글남기기