[파이썬 기본 3] 머신러닝 필수 라이브러리 :: 넘파이 총정리
앞서 말했다시피, 머신러닝/인공지능/데이터사이언스에서는 필수적으로 파이썬을 알고있어야 하기에 우선 파이썬의 기본적인 부분에 대해 포스팅을 연재하고 있다.
<이전 글 보기>
[파이썬 기본 2] 조건문(If문/else문/elif문), 반복문(while문/for문)
[파이썬 기본 1-2] 자료형(문자열/콜렉션), 함수 정의
[파이썬 기본 1-1] 초기 세팅 및 변수, 연산자, sep, input, 형변환, eval()
참고) 주피터 노트북 사용방법
→ Anaconda3
→ Jupyter Notebook 실행
※ 참고
주피터노트북은 print로 출력하지 않는 이상, head 등 특정 구문을 출력해주는 함수는 마지막에 요청한 구문만 출력하는 특징이 있다. 따라서, print를 제외한 특정 구문을 함께 출력하는 경우, print로 명시적으로 출력문을 짜야 여러개가 출력된다.
1. NumPy (Numerical Python)
<명령어 요약>
np.array([~~~]) : 넘파이 배열 생성
type(*) : *변수의 타입(자료형) 확인
*.shape : *넘파이 행렬의 행렬 확인
*.ndim : * 넘파이 행렬 의 차원 확인
*.dtype : * 넘파이 행렬 의 배열요소 중 가장 큰 데이터 타입으로 변환
*.astype('자료형') : * 넘파이 행렬의 배열요소의 자료형을 괄호안의 자료형으로 변환
*.itemsize : 각 요소의 데이터 크기를 출력
*.size : 각 요소의 개수를 출력
*.nbytes: 행렬의 총 데이터 크기를 출력 (itemsize X size로 계산됨)
*.T : 행렬의 Transpose 행렬 출력
*.transpose() : 행렬의 Transpose 행렬 출력 (*.T와 결과 동일)
변수 = np.transpose(A) : 행렬 A를 전치행렬(Transpose)하여 그 결과를 변수에 저장
np.arange(a) : 배열 요소를 0부터 a-1까지 배열 생성
np.arange(a, b) : 배열 요소를 a부터 b-1까지 배열 생성
np.zeros((a,b), dtype='자료형') : a행 b열 넘파이 배열을 '자료형' 타입으로 0행렬 생성 (자료형 미입력시 기본 float64)
np.ones((a,b), dtype='자료형') : a행 b열 넘파이 배열을 '자료형' 타입으로 1행렬 생성 (자료형 미입력시 기본 float64)
np.full((a,b), c) : a행 b열 넘파이 배열을 c 값으로 모두 채워서 정의
np.eye(n) : n행 n열의 단위행렬(I) 생성
*.shape(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 불가)
*.reshape(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 가능)
값 대신 -1을 넣으면 알아서 최적으로 수행하라는 뜻.
지정한 차원과 크기로 변경하지 못하면 오류 발생시킨다. 배열 요소의 개수가 정확하게 일치해야 한다.
*.resize(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 불가)
*[n] = *넘파이 행렬의 n번째 단일 값을 출력(0번부터 시작)
*[-n] = *넘파이 행렬의 뒤에서 n번째 단일 값을 출력(-1번은 맨 끝을 의미)
*[n:m] = *넘파이 행렬의 n~m-1째 값을 출력 (0번부터 시작)
*[:m] = *넘파이 행렬의 처음부터 m-1까지 값을 출력 (0번부터 시작)
*[m:] = *넘파이 행렬의 m번부터 끝까지 값을 출력 (0번부터 시작)
*[:] = *넘파이 행렬의 처음부터 끝까지 값을 출력
*[n, m] = *넘파이 행렬의 n행 m+1열의 값을 출력(0행부터 시작)
*[n:n', m:m'] = *넘파이 행렬의 n~n'-1행 m~m'-1열의 값을 출력 (0행부터 시작)
*[n:, m:m'] = *넘파이 행렬의 n행~끝까지 m열~m'-1열의 값을 출력 (0행부터 시작)
*[:n, m:m'] = *넘파이 행렬의 처음부터 n-1행 m'-1열의 값을 출력 (0행부터 시작)
*[:, :] = *넘파이 행렬 전체 값을 출력
*[n:, 0] = *넘파이 행렬의 n행~끝까지 0열의 값을 출력
[* > n] = *넘파이 행렬의 값이 n보다 크면 True를 리턴한다.
* = np.random.randn(a,b) : aXb 행렬에 난수(평균0, 표준편차1)를 발생하여 * 변수에 저장
a = b : 얕은 복사. a와 b는 동일한 데이터로, a 또는 b를 수정하면 둘다 값이 바뀜 (주소값을 공유)
a = b.copy : 깊은 복사. a와 b는 완전 독립적인 별개로, 각각 수정이 영향을 안끼침 (별도의 주소값 사용)
변수 = np.sort(*) : *넘파이 행렬을 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*)[::-1] : *넘파이 행렬을 내름차순 정렬한 결과를 변수에 저장
*.sort() : *넘파이 행렬을 오름차순 정렬하고 원본에 저장
변수 = np.sort(*, axis=0) : *다차원 넘파이 행렬을 열 기준으로 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=1) : *다차원 넘파이 행렬을 행 기준으로 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=0)[::-1] : *넘파이 행렬을 열 기준으로 내름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=1)[::-1] : *넘파이 행렬을 행 기준으로 오름차순 후 행을 역순 배치한 결과를 변수에 저장
변수 = np.sort(*, axis=1)[:, ::-1] : *넘파이 행렬을 행 기준으로 내름차순 정렬한 결과를 변수에 저장
변수 = np.argsort(*) : *1차원 넘파이 행렬을 오름차순 정렬 후 해당하는 인덱스를 반환
변수 = np.argsort(*)[::-1] : *1차원 넘파이 행렬을 내림차순 정렬 후 해당하는 인덱스를 반환
변수 = np.argmax(*) : *1차원 넘파이 행렬 중 가장 중복이 많은 큰 값에 해당하는 인덱스를 반환
변수 = np.dot(A,B) : 행렬 A와 B를 내적(행렬곱)하여 그 결과를 변수에 저장
변수 = np.cross(A, B) : 행렬 A와 B를 외적하여 그 결과를 변수에 저장
a = np.unique(*, return_counts=False) : * 배열의 중복을 제거한 값들을 a에 저장 (대문자 주의)
a, b = np.unique(*, return_counts=True) : * 배열의 중복을 제거한 값들을 a에 저장하고, 중복 개수를 b에 저장 (대문자 주의)
<사용하는 이유>
파이썬의 list로 동일한 선형대수 및 행렬 연산을 할 수 있지만, NumPy가 속도차이가 월등하게 좋다.
사용방법은 라이브러리를 import하고 정의하여 사용하면 된다.
<사용방법>
① import numpy as np 명령으로 numpy라이브러리를 np에다 정의한다. np는 넘파이를 뜻하는 변수명의 관례이다.
② 변수명 = np.array() 명령으로 특정 변수를 넘파이 행렬로 정의한다.
1) 넘파이 행렬 정의
np.array([~~~]) : 넘파이 배열 생성
type(*) : *변수의 타입(자료형) 확인
np.array로 정의하는 넘파이 행렬(배열)을 ndarray라고 부른다. N-dimensional Array의 약자이며, 1차원배열을 포함한 N차원 배열을 가리킨다. (앞으로 넘파이 행렬을 ndarray라고 명명하겠다.)
<참고> : 배열의 기초
머신러닝에서 행렬의 차원을 shape라는 개념으로 표현한다.
행렬 [m,n]에서 m=행, n=열을 의미하며, 아래 그림을 참고하기 바란다.
<참고> : 배열의 인덱싱
배열의 특정 위치를 정의하는 행위를 인덱싱이라고 한다. 첫 행과 첫 열은 0으로 표현된다.
<사용 예2>
import numpy as np
array2 = np.array([1,2,3],[2,3,4])
print(type(array2))
print(array2.shape)
<출력 결과2>
array2에 넘파이 배열 [[1,2,3],[2,3,4]]을 정의하였고, 이 타입은 numpy.ndarray 타입(넘파이로 정의된 배열타입)이며, shape는 (2,3) 즉, 2행 3열 [2,3] 행렬이라는 뜻이다.
<사용 예3>
import numpy as np
array3 = np.array([[1,2,3]])
print(type(array3))
print(array3.shape)
<출력 결과3>
array3에 넘파이 배열 [[1,2,3]]을 정의하였고, 이 타입은 numpy.ndarray 타입(넘파이로 정의된 배열타입)이며, shape는 (1,3) 즉, 1행 3열 [1,3] 행렬이라는 뜻이다.
★ 주의 ★
[1,2,3] = 값 3개로 구성된 1차원배열라는 뜻
np.array([1,2,3]) = 값 3개로 구성된 1차원배열라는 뜻
np.array([[1,2,3]]) = 1행 3열로 구성된 행렬이라는 뜻
하지만, 둘 다 numpy.ndarray 타입(넘파이로 정의된 배열타입)으로 나온다.
<예시4>
(L5) : 리스트 정의
(L6) : 넘파이 배열로 정의 후 a에 대입
(L7) : 4개 요소의 1차원 배열 shape 출력
(L8) : a[0]의 값 1 출력
(L11) : 2차원 넘파이 배열 정의 후 b에 대입
(L12) : 2행 3열의 2차원 배열 shape 출력
(L13) : 0행 0열 값 1 출력
(L14) : 0행 값 [1 2 3] 출력
2) 넘파이 행렬 속성 함수
(1) shape
*.shape : *넘파이 행렬의 행렬 확인
ndarray는 행렬이므로 *.shape가 가능하지만, list는 행렬이 아니므로 *.shape함수가 먹지 않는다.
<예시>
import numpy as np
array1 = np.array([1,2,3])
print(type(array1))
print(array1.shape)
<출력 결과>
array1에 넘파이 배열 [1,2,3]을 정의하였고, 이 타입은 numpy.ndarray 타입(넘파이로 정의된 배열타입)이며, shape는 (3,) 즉, 3개의 값으로 이루어진 1차원 배열(리스트)이라는 뜻이다.
(2) ndim
*.ndim : n차원(n Dimension)을 알려주는 명령어로, array1~3 각각 1차원, 2차원, 2차원을 가리킨다.
<예시>
(3) dtype
*.dtype: 데이터 타입 중 가장 큰 데이터 타입으로 데이터 타입 변환하는 명령어
<예시1>
1,2,3 모두 int이므로 int32로 데이터 타입이 변환되었다.(원래 int32였으므로, 변환된것이 아님)
<예시2>
1,2,3 모두 int이므로 int32로 데이터 타입이 변환되었다.(원래 int32였으므로, 변환된것이 아님)
<예시3>
큰 타입인 test의 자료형, 문자열(U11)로 변환
(4) astype
*.astype('자료형') : * 넘파이 행렬의 배열요소의 자료형을 괄호안의 자료형으로 변환
<예시1>
각각 float인 요소들을 int32로 데이터 타입으로 변환.
자료형을 변환함에 따라 소수점이 사라졌다.
<예시2>
(L4) a 변수의 데이터 타입 출력 (float 64비트)
(L7) a_i8 변수에 int8 데이터 타입 변환하여 저장
(L8) a_i8 변수의 데이터 타입 출력 (int 8비트)
(5) itemsize, size, nbytes, T
*.itemsize : 각 요소의 데이터 크기를 출력
*.size : 각 요소의 개수를 출력
*.nbytes: 행렬의 총 데이터 크기를 출력 (itemsize X size로 계산됨)
*.T : 행렬의 Transpose 행렬 출력
*.transpose() : 행렬의 Transpose 행렬 출력 (*.T와 결과 동일)
변수 = np.transpose(A) : 행렬 A를 전치행렬(Transpose)하여 그 결과를 변수에 저장
<참고> 전치행렬(Transpose) 정의
전치행렬은 아래 예시들과 같이 행이 열이되고 열이 행이되는 행렬이다.
특히 정사각형 행렬(2x2, 3x3 등)의 전치행렬은 가운데 행렬을 기준으로 xy대칭을 한 것이라고 생각하면 편하다.
<예시1>
(L7) 넘파이 행렬 arr의 각 요소당 데이터 크기는 8바이트이다.
(L8) 행렬에서 각 요소들의 개수는 총 6개이다.
(L9) 행렬의 데이터 크기는 8바이트 X 6개 = 48 바이트이다.
(L10) [0 1 2] [3 4 5]의 Transpose 행렬을 출력(행렬반전)
<예시2>
a.T와 a.transpose()는 표현방식만 다를 뿐 모두 동일한 결과가 출력된다.
<예시3>
이 또한 위와 동일한 결과가 출력된다. 표현의 차이이다.
3) 넘파이 행렬 정의함수
(1) arange() 함수 : 배열 생성
np.arange(a) : 배열 요소를 0부터 a-1까지 배열 생성
np.arange(a, b) : 배열 요소를 a부터 b-1까지 배열 생성
<예시>
(2) zeros() / ones() : 영행렬/일행렬 정의
np.zeros((a,b), dtype='자료형') : a행 b열 넘파이 배열을 '자료형' 타입으로 0행렬 생성 (자료형 미입력시 기본 float64)
np.ones((a,b), dtype='자료형') : a행 b열 넘파이 배열을 '자료형' 타입으로 1행렬 생성 (자료형 미입력시 기본 float64)
<예시1> - zeros
3x2 영행렬 생성 (자료형은 int로 정의)
<예시2> - ones
3x2 일행렬 생성 (자료형은 미정의됐으므로 float로 정의)
(3) full() : 특정 값으로 행렬 정의
np.full((a,b), c) : a행 b열 넘파이 배열을 c 값으로 모두 채워서 정의
<예시>
2행 3열의 넘파이 행렬을 5로 채워넣고 변수 d에 저장
(4) eye() : 단위행렬(I) 생성
np.eye(n) : n행 n열의 단위행렬 생성
<예시>
3행 3열의 넘파이 행렬의 단위행렬(I) 생성
4) 넘파이 행렬 차원 변경
(1) shape, reshape, resize : n차원 변경
*.shape(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 불가)
*.reshape(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 가능)
값 대신 -1을 넣으면 알아서 최적으로 수행하라는 뜻.
지정한 차원과 크기로 변경하지 못하면 오류 발생시킨다. 배열 요소의 개수가 정확하게 일치해야 한다.
*.resize(a,b) : *넘파이 행렬의 차원을 axb 행렬로 차원변경 (변수 대입 불가)
<예시1> - shape, reshape, resize 셋 모두 동일한 결과가 출력된다.
(L6~8) shape 함수를 이용하여 차원 변경시, 다른 변수에 대입이 불가하다.
(L11~12) reshape 함수를 이용하여 차원 변경시, 다른 변수에 대입이 가능하다.
(L18~19) resize 함수를 이용하여 차원 변경시, 다른 변수에 대입이 불가하다.
<예시2>
reshape를 이용하여 1x10 행렬인 array1을 2x5의 array2로 차원변경, 5x2의 array3으로 차원 변경 수행
<예시3>
배열요소가 10개밖에 없는데, 4x3 (12개 요소)로 변경하려고 하면 에러가 난다.
<예시4>
reshape를 이용하여 특정 행 또는 열에 값 대신 -1을 넣게 되면, 에러가 나지 않는 유일값을 알아서 넣어준다.
(2) flatten : 1차원 배열로 변경
*.flatten() : *넘파이 행렬의 차원을 1차원으로 변경
<예시>
2X4의 2차원 배열을 1차원 배열로 변경
5) 넘파이 행렬의 일차원 값 인덱싱 & 슬라이싱
*[n] = *넘파이 행렬의 n번째 단일 값을 출력(0번부터 시작)
*[-n] = *넘파이 행렬의 뒤에서 n번째 단일 값을 출력(-1번은 맨 끝을 의미)
*[n:m] = *넘파이 행렬의 n~m-1째 값을 출력 (0번부터 시작)
*[:m] = *넘파이 행렬의 처음부터 m-1까지 값을 출력 (0번부터 시작)
*[m:] = *넘파이 행렬의 m번부터 끝까지 값을 출력 (0번부터 시작)
*[:] = *넘파이 행렬의 처음부터 끝까지 값을 출력
<참고> : 배열의 슬라이싱
배열의 특정 부분을 잘라서 표현하는 것을 의미한다. 아래 그림을 참고하자
(a) 처음 값은생략할 수 있으며, 0부터2행까지, 0부터2열까지를 의미한다.
(b) 처음 값, 끝값은 생략할 수 있으며,전체 행, 1열부터 끝까지를 의미한다.
(c) 0행 전체를 의미한다.
(d) 2행전체, 1열부터 끝까지를 의미한다.
<예시1>
3번째 값인 3을 출력한다.
<예시2>
뒤에서 1번째, 2번째인 각각 9, 8을 출력한다.
<예시3>
0부터 2번째 값인 1,2,3을 출력한다.
<예시4>
array4(0,1,2번째 값 출력), array5(3번째 이후 값 출력), array6(전체 값 출력)를 출력한다.
6) 넘파이 행렬의 다차원 값 인덱싱 & 슬라이싱
*[n, m] = *넘파이 행렬의 n행 m+1열의 값을 출력(0행부터 시작)
*[n:n', m:m'] = *넘파이 행렬의 n~n'-1행 m~m'-1열의 값을 출력 (0행부터 시작)
*[n:, m:m'] = *넘파이 행렬의 n행~끝까지 m열~m'-1열의 값을 출력 (0행부터 시작)
*[:n, m:m'] = *넘파이 행렬의 처음부터 n-1행 m'-1열의 값을 출력 (0행부터 시작)
*[:, :] = *넘파이 행렬 전체 값을 출력
*[n:, 0] = *넘파이 행렬의 n행~끝까지 0열의 값을 출력
※ 출력되는 결과가 1차원인 경우, 세로로 출력되지 않고 무조건 가로로 출력된다.
<예시1>
각각 [0,0] [0,1] [1,0] [2,2] 행렬 값인 1,2,4,9를 출력한다.
<예시2>
본 예시에 대한 해설은 아래와 같다.
array2d =
[1 2 3]
[4 5 6]
[7 8 9]
(1) array2d[0:2, 0:2] = 0~1행, 0~1열 2x2 행렬을 출력하는 것이므로
[1 2]
[4 5]
가 된다.
(2) array2d[1:3, 0:3] = 1~2행, 0~2열 2x3 행렬을 출력하는 것이므로
[4 5 6]
[7 8 9]
가 된다.
(3) array2d[1:3, :] = 1~2행, 모든열(0~2열) 2x3 행렬을 출력하는 것이므로 (2)와 동일한
[4 5 6]
[7 8 9]
가 된다.
(4) array2d[:, :] = 모든행(0~2행), 모든열(0~2열) 3x3 행렬을 출력하는 것이므로 array2d와 동일한
[1 2 3]
[4 5 6]
[7 8 9]
가 된다.
(5) array2d[:2, 1:] = 0~1행, 1~끝열(2열) 2x2 행렬을 출력하는 것이므로
[2 3]
[5 6]
가 된다.
(6) array2d[:2, 0] = 0~1행, 0열 2x1 행렬을 출력하는 것이므로
[1]
[4]
가 되지만, 출력되는 것이 1차원 행렬이므로
[1 4]가 출력된다.
<예시3>
본 예시에 대한 해설은 아래와 같다.
array2d = 1~9까지 1차원 배열을 array1d에 만들고, 이를 3x3행렬로 array2d를 만든다.
[1 2 3]
[4 5 6]
[7 8 9]
(1) array2d[[0,1], 2] = 0,1행, 2열 2x1 행렬을 출력하는 것이므로, 1차원 행렬
[3 6]
가 된다.
(2) array2d[[0,1], 0:2] = 0,1행, 0~1열 2x2 행렬을 출력하는 것이므로
[1 2]
[4 5]
가 된다.
(3) array2d[[0, 1]] = 0,1행 전체를 출력하는 것이므로
[1 2 3]
[4 5 6]
가 된다.
★주의★
array2d[0, 1] 의 경우, 0행 1열에 있는 단일 값(2)을 불러오는 것인데 반해,
array2d[[0, 1]] 의 경우, 0행과 1행 전부를 출력하는 것이므로 2x3 행렬이 된다.
(4) array2d[[0, 2], 1] = 0,2행 1열 2x1 행렬을 출력하는 것이므로(1차원 행렬)
[2 8]
이 된다.
7) 불린 인덱싱(마스킹)
조건문 만족 여부에 따라 각각 True / False로 출력되는 것을 이용하여 조건에 맞는 값을 출력하게 할 수 있다. True값들만 출력하는 것을 마스킹한다고 표현한다.
[* > n] = *넘파이 행렬의 값이 n보다 크면 True를 리턴한다.
* = np.random.randn(a,b) : aXb 행렬에 난수(평균0, 표준편차1)를 발생하여 * 변수에 저장
<예시1>
array1d의 값이 5보다 큰 값들을 array3에 저장한다.
<예시2>
5보다 큰 경우를 print하게 되면 조건만족에 따라 False와 True를 리턴하게 된다.
<예시3>
(L2) mask에 1차원 행렬을 boolean 타입으로 [False, True, True, False]로 정의한다.
(L5) 4행 2열 배열을 만들고 난수 발생하여 값을 저장한다.
(L8) 마스킹된 데이터인 2행, 3행을 출력한다.
(L9) 마스킹되지 않은 데이터인 1행, 4행을 출력한다.
8) 얕은복사와 깊은복사
a = b : 얕은 복사. a와 b는 동일한 데이터로, a 또는 b를 수정하면 둘다 값이 바뀜 (주소값을 공유)
a = b.copy : 깊은 복사. a와 b는 완전 독립적인 별개로, 각각 수정이 영향을 안끼침 (별도의 주소값 사용)
<예시1> - 얕은 복사
(L5) a 와 b는 완전히 같은가에 대한 질문에 True 리턴
(L7~8) b의 0번값을 10으로 변경 후 a 배열 출력시 바뀐것을 확인할 수 있음
(L9~10) a의 1번값을 20으로 변경 후 b 배열 출력시 바뀐것을 확인할 수 있음
<예시2> - 깊은 복사
(L3) a 배열을 깊은복사하여 c에 저장
(L5~7) c 배열의 0번값을 20으로 바꾸더라도, a 배열에는 영향이 없다.
9) 넘파이 행렬 정렬 (sort)
변수 = np.sort(*) : *넘파이 행렬을 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*)[::-1] : *넘파이 행렬을 내름차순 정렬한 결과를 변수에 저장
*.sort() : *넘파이 행렬을 오름차순 정렬하고 원본에 저장
변수 = np.sort(*, axis=0) : *다차원 넘파이 행렬을 열 기준으로 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=1) : *다차원 넘파이 행렬을 행 기준으로 오름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=0)[::-1] : *넘파이 행렬을 열 기준으로 내름차순 정렬한 결과를 변수에 저장
변수 = np.sort(*, axis=1)[::-1] : *넘파이 행렬을 행 기준으로 오름차순 후 행을 역순 배치한 결과를 변수에 저장
변수 = np.sort(*, axis=1)[:, ::-1] : *넘파이 행렬을 행 기준으로 내름차순 정렬한 결과를 변수에 저장
변수 = np.argsort(*) : *1차원 넘파이 행렬을 오름차순 정렬 후 해당하는 인덱스를 반환
변수 = np.argsort(*)[::-1] : *1차원 넘파이 행렬을 내림차순 정렬 후 해당하는 인덱스를 반환
변수 = np.argmax(*) : *1차원 넘파이 행렬 중 가장 중복이 많은 큰 값에 해당하는 인덱스를 반환
<예시1>
(L5) 배열을 오름차순 정렬한 값을 출력
(L8) 배열을 오름차순 했을때의 인덱스를 출력
(L10~11) 배열을 오름차순 정렬하고 원본 수정 후 그 결과를 출력
<예시2>
org_array에 저장된 [3,1,9,5]를 오름차순 정렬 후 sort_array1에 저장. 저장된 값은 [1 3 9 5] 이다.
sort2_array = org_array.sort() 문장을 수행하면 원본인 org_array를 오름차순 정렬한다(원본이 수정됨). sort2_array에 별도로 저장되는 것이 아니므로 변수를 대입연산할 필요는 없다. 즉, org_array.sort()만 입력해도 원본이 정렬된다.
<예시3>
sort_array1에 org_array가 내림차순으로 정렬 후 저장됨
<예시4>
(1) sort1 = 원본 행렬을 열 기준으로 오름차순 정렬
(2) sort2 = 원본 행렬을 행 기준으로 오름차순 정렬
(3) sort3 = 원본 행렬을 열 기준으로 내림차순 정렬
(4) sort4 = 원본 행렬을 행 기준으로 오름차순 정렬 후 행을 역순 배치. 즉, [1행,2행,3행] → [3행, 2행, 1행]으로 배치됨
(5) sort5 = 원본 행렬을 행 기준으로 내림차순 정렬
<예시 5>
(1) sort_indices = org_array를 오름차순 후 여기에 대응되는 인덱스를 반환한다. [3, 1, 9, 5] = [0, 1, 2, 3]의 인덱스로 정의되는데, [1, 3, 5, 9]로 정렬하게 되면 이 인덱스는 [1, 0, 3, 2]로 배치된 결과를 저장한다.
(2) sort_indices = org_array를 내림차순 후 여기에 대응되는 인덱스를 반환한다. [3, 1, 9, 5] = [0, 1, 2, 3]의 인덱스로 정의되는데, [9, 5, 3, 1]로 정렬하게 되면 이 인덱스는 [2, 3, 0, 1]로 배치된 결과를 저장한다.
<예시6> - 인덱스 반환을 어떻게 활용할 수 있을까?
위 예시는 반 학생의 이름과 점수를 각각 array로 만들어주고, 점수를 오름차순한 결과를 인덱스로 sort_indices 변수로 리턴받는다. 그 인덱스에 해당하는 이름을 출력하게 되면, 낮은점수 순으로 반 학생의 이름을 출력할 수 있다.
엑셀로 표를 만들고 나서 각 열들을 array로 불러들여온 후에 인덱스를 이용하여 이에 대응되는 데이터를 손쉽게 조작하는 방법으로 활용할 수 있다.
10) 넘파이 행렬의 내적/외적
변수 = np.dot(A,B) : 행렬 A와 B를 내적(행렬곱)하여 그 결과를 변수에 저장
변수 = np.cross(A, B) : 행렬 A와 B를 외적하여 그 결과를 변수에 저장
들어가기에 앞서, 내적/외적/전치행렬에 대해 간단히 알아보도록 하자.
※ 내적(행렬곱) 정의
내적의 정의이다. 내적은 두 벡터의 곱으로 그 값은 스칼라가 된다.
우선 내적(행렬곱은)하는 방법은 아래 그림과 같이 설명할 수 있으며, [axb] X [cxd] 행렬을 내적(행렬곱)하기 위해서는 b = c 여야만 하고, 내적(행렬곱)한 결과는 axd 행렬로 나타낼 수 있다.
※ 외적 정의
벡터 a에서 b방향으로 오른손을 감았을때 엄지손가락의 방향이 외적의 방향이다. 내적은 스칼라값으로 나타나지만 외적은 다시 벡터의 형태로 나타난다는 것을 알 수 있다.
두 벡터 a와 b의 외적 계산 방법은 아래와 같다.
두 벡터를 i, j, k성분으로 나누고 오른쪽 대각선은 더하기, 왼쪽 대각선은 빼기로 해주면 외적 벡터를 구할 수 있다.
<예시1> - 내적
위의 정의를 보면 어떻게 계산되었는지 쉽게 이해가 가능할 것으로 생각되어 별도의 설명은 생략하겠다.
<예시2> - 외적
위의 정의를 보면 어떻게 계산되었는지 쉽게 이해가 가능할 것으로 생각되어 별도의 설명은 생략하겠다.
<Practice> :: 우수 초콜릿 분석
시중에 판매되는 초콜릿 중에 우수 상품의 특징을 알고 싶습니다. 초콜릿에 1점부터 5점 사이의 평점을 매긴 데이터를 분석해 봅시다. 아래 제공하는 ‘chocolate_rating.csv’ 파일을 사용합니다. 파일의 a,b,c,d열은 각각 순번, 생산년도, 카카오 함유량, 평점 입니다.
1. loadtxt() 함수를 사용해서 데이터를 읽어오기(n차원배열, n행m열, 원소 총 개수, 행렬의 값(int로 표현))
2. 모든 초콜릿의 평점 구하기
3. 평점 4점 이상인 우수 초콜릿의 개수와 초콜릿 번호를 구하기 (정수로 표현)
4. unique() 함수를 사용하여 우수 초콜릿의 카카오 함유량(%) 종류와 각 함유량 당 우수 초콜릿 갯수(빈도수, count) 구하기
5. 가장 빈도수가 큰 카카오 함유량(%) 구하기
(우수 초콜릿 n가지 중 m 가지의 카카오 함유량이 xx%입니다. 형태로 출력)
import numpy as np
data = np.loadtxt('chocolate_ranking.csv', delimiter=',')
print('차원:', data.ndim)
print('모양:', data.shape)
print('원소 수:', data.size)
print(data)
ratings_mean = data[:,3].mean( )
print(ratings_mean)
high_level = data[data[:,3] >= 4]
high_id = high_level[:,0].astype(np.int64)
print('우수 초콜릿 수:', high_id.size)
print(high_id)
high_kakao = high_level[:,2]
unique_values, value_counts = np.unique(high_kakao, return_counts=True)
print('카카오 함유량:', unique_values)
print('함유량별 빈도수:', value_counts)
5.우수 초콜릿 중 가장 빈도수가 큰 카카오 함유량을 구함.
max_index = np.argmax(value_counts)
print(unique_values[max_index])
print('우수 초콜릿', high_id.size, '가지 중', value_counts[max_index],\
'가지의 카카오 함유량이', unique_values[max_index] * 100, '%입니다.')
'IT > 머신러닝 & 인공지능 & 데이터사이언스' 카테고리의 다른 글
[파이썬 기본 4] 머신러닝 필수 라이브러리 :: 판다스 총정리 (0) | 2023.10.05 |
---|---|
[파이썬 기본 2] 조건문(If/else/elif문), 반복문(while문/for문) (0) | 2023.10.05 |
[파이썬 기본 1-2] 자료형(문자열/콜렉션), 함수 정의 (1) | 2023.10.05 |
[파이썬 기본 1-1] 초기 세팅 및 변수, 연산자, sep, input, 형변환, eval() (0) | 2023.09.25 |