[파이썬/머신러닝] NUMPY(넘파이) 기본 익히기
[파이썬/머신러닝] NUMPY(넘파이) 기본 익히기
ndarray의 차원, 크기 변경하는 reshape
import numpy as np
array1 = np.arange(10)
print('array1 : ', array1)
array2 = array1.reshape(2,5)
print('array2 : ', array2)
array3 = array1.reshape(5,2)
print('array3 : ', array3)
1차원으로 생성된 ndarray를 2차원 ndarray로 환해 주는 메소드 입니다.
위 예시에서는 1차원 ndarray 를 2X5, 5X2 형태의 2차원 ndarray로 변환합니다. 여기서 사이즈가 다르다면 변경할 수 없습니다.
array1을 2X6 또는 3X2 등으로 변환하려고 하면 에러가 발생합니다.
import numpy as np
array1 = np.arange(10)
print('array1 : ', array1)
array2 = array1.reshape(2,-1)
print('array2 : ', array2)
array3 = array1.reshape(-1,2)
print('array3 : ', array3)
reshape()의 인자값으로 -1을 넣어주면 유연하게 변경이 가능합니다.
reahape() 메소드의 인자를 차례로 행과 열이라고 생각하고 보면 array2는 array1의 값에 행을 2로 고정시켰을 때 맞는 값을 찾아서 열로 변환해줍니다. array3는 array1의 값에 열을 2로 고정시켰을때 맞는 값을 찾아 행으로 변환해줍니다.
이것도 마찬가지로 사이즈가 다르다면 형태를 변환할 수 없습니다.
axis 0은 row 방향축, axis x는 column 방향축 임을 기억하자
슬라이싱으로 데이터 추출하기
import numpy as np
array1 = np.arange(start = 1, stop = 10)
print(array1)
array2 = array1[0:3]
print(array2)
import numpy as np
array1 = np.arange(start = 1, stop = 10)
array3 = array1[:3]
print(array3)
array4 = array1[3:]
print(array4)
array5 = array1[:]
print(array5)
콜론(:) 사이의 시작, 종료 인덱스는 생략이 가능합니다.
콜론(:) 앞의 인덱스 생략하면 처음인 인덱스 0으로, 뒤의 인덱스를 생략하면 마지막 인덱스로 간주하고 둘다 생략했을때는 처음~끝의 인덱스로 간주합니다.
import numpy as np
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print(array2d)
print('array2d[0:2, 0:2] : ', array2d[0:2, 0:2])
print('array2d[1:3, 0:3] : ', array2d[1:3, 0:3])
print('array2d[1:3, :] : ', array2d[1:3, :])
print('array2d[: , :])', array2d[: , :])
앞에서 익힌 슬리이싱으로 범위를 지정해 반환시킬수도 있습니다.
import numpy as np
array1d = np.arange(start=1, stop=10)
array2d = array1d.reshape(3,3)
print(array2d)
print('\n')
print(array2d[0])
print(array2d[2])
2차원 ndarray인 array2d를 array2d[0], array2d[1]과 같이 뒤에오는 인덱스를 없애면 axis 0 (row축)의 첫번째 로우 ndarray를 반환합니다. 반환되는 ndarray는 1차원 입니다.
팬시 인덱싱
import numpy as np
array1d = np.arange(start = 1, stop =10)
array2d = array1d.reshape(3,3)
print(array2d, '\n')
array3 = array2d[[0,1],2]
print('array2d[[0,1],2] : ', array3.tolist())
print('\n')
array4 = array2d[[0,1], 0:2]
print('array2d[[0,1], 0:2] : ', array4.tolist())
불린(boolean) 인덱싱
import numpy as np
array1d = np.arange(start = 1, stop =10)
print(array1d, '\n')
array2 = array1d[array1d>5]
print(array1d>5)
print(array2)
ndarray의 인덱스를 지정하는 [] 내 조건문을 그대로 넣으면 조건에 맞는 결과값이 반환됩니다. 왜냐하면 위 예제에서 'array1d>5' 라는 조건 식 자체가 true, false의 결과를 내는 ndarray 형태로 반환되기 때문입니다. 조건식으로 반환된 값을 ndarray의 인자로 넣기 때문에 결과로 array2가 출력되게 됩니다.
이 기능은 굉장히 편한거 같네요. 이 기능 없이 구현 하려면 for 문을 이용해 인덱스 하나하나 접근해서 if문으로 5보다 크다는 조건을 걸어줘서 구해야 할테니 말이에요.
행렬 정렬
import numpy as np
ori_array = np.array([3,4,2,7,5,9,1])
print(ori_array, '\n')
sort_array1 = np.sort(ori_array)
print(sort_array1)
print('origin array : ', ori_array)
print('\n')
sort_array2 = ori_array.sort()
print(sort_array2)
print('origin array : ', ori_array)
#sort_array3 = np.sort(ori_array)[::-1]
#print('origin array desc : ', sort_array3)
ori_array.sort()[::-1]
print('origin array desc : ', ori_array)
두가지 정렬 방법이 있는데 np.sort()를 이용하게 되면 원본 행렬에는 영향을 주지 않고 sort 된 값을 반환해서 넘겨주지만, ndarray.sort()를 이용하면 원본 자체를 sort하게 됩니다. sort()는 기본적으로 오름차순이고 내림차순을 하려면 [::-1]을 적용합니다.
import numpy as np
array2d = np.array([[9,6],
[4,1]])
sort_array2d_axis0 = np.sort(array2d, axis = 0)
print(sort_array2d_axis0) # row 방향 정렬
print('\n')
sort_array2d_axis1= np.sort(array2d, axis = 1)
print(sort_array2d_axis1)
axis를 이용해 로우와 컬럼에 따라 정렬하는 방법도 있습니다. 정렬 속성 값에 axis 값만 넣어주면 됩니다.
정렬된 행렬의 인덱스 반환하기
import numpy as np
ori_array = np.array([3,1,9,5])
sort_indices = np.argsort(ori_array)
sort_array = np.sort(ori_array)
print(ori_array)#원본
print(sort_array)#sort 후 행렬
print(sort_indices)#정렬된 행렬 값의 최초 원본 인덱스 값을 보여줌
글로 설명하는게 좀 힘든데 우선 최초의 ori_array 값이 3, 1, 9, 5 가 있습니다. 각 값이 가지는 인덱스는 3이 0, 1은 1, 9는 2, 5는 3이 되겠지요. ori_array의 값을 sort 하면(오름차순) sort_array와 같이 1, 3, 5, 9가 나오게 되는데 이렇게 정렬된 상태에서 각 값들이 원본 행렬에서 가졌던 인덱스 값을 출력해 주는게 argsort() 입니다. 1,3,5,9 의 값을 가지고 1은 원본 행렬일때 인덱스가 1이 었기 때문에 1, 3은 원본 행렬일때 0, 5는3, 9는 2를 가졌었기 때문에 1,0,3,2 가 출력되는 것입니다. 이해하면 간단한데 글로 풀어 쓰니까 헷갈릴 수도 있을 거 같네요.
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(sort_indices_asc)
print(name_array[sort_indices_asc])
ndarray는 RDMS처럼 테이블 컬럼이나 판다스의 DataFrame같은 메타데이터를 가질 수 없어 실제값과 그 값이 뜻하는 메타데이터를 별도의 ndarray를 각각 가져야 한다고 책에서 설명하고 있어요.
위의 예시처럼 이름과 점수를 각 각의 ndarray로 가진 다음(이름과 점수의 인덱스가 서로 동일한 것이 짝) 점수를 오름차순을 하고 정렬한 점수에 맞는 인덱스를 찾아서 구해줄 수 있습니다.
※ [파이썬 머신러닝 완전정복] 책으로 학습하고 해당 내용을 실습해서 블로그로 정리합니다. 해당 내용은 책에 수록된 예시 입니다.