[Capstone Study] 머신러닝 완벽 가이드

[머신러닝] 섹션 1.3 넘파이 (2)

wlalsu_u 2023. 11. 6. 01:35

https://wlalsu.tistory.com/110?category=670879

 

[머신러닝] 섹션 1.3 넘파이 (1)

1.3.1 넘파이(NumPy) 란? 1) Numercial Python 를 의미 2) 선형대수 기반의 프로그램을 쉽게 만들 수 있도록 지원하는 대표적인 패키지 - 많은 머신러닝 알고리즘이 넘파이를 기반으로 작성되어 있음 - 대

wlalsu.tistory.com

 

 

 

 

 

 

 

1.3.6 넘파이의 ndarray의 데이터 세트 선택하기 - 인덱싱(Indexing) 

 

 

 

넘파이의 ndarray 에 있는 일부 데이터 세트나 특정 데이터를 선택하는 방식은 다음과 같다.

 

 

 

 

1. 단일 값 추출

 

 

- 한 개의 데이터만을 추출하는 방법

 

- 원하는 위치의 인덱스 값을 지정 시, 해당 위치 데이터 반환

 

- 추출하고자 하는 위치의 인덱스 값을 [ ] 안에 입력

 

 

 

 

일차원 ndarray 에서 단일 값 추출을 위한 예시는 아래와 같다.

 

 

 

 

 

 

여기에서 인덱스는 0부터 시작하므로,

 

array1[2] 는 2번째 데이터 값이 아닌, 3번째 데이터 값임을 유의하자!

 

 

또한 type(value) 값을 확인해보면,

 

array1[2] 의 데이터 타입은 더 이상 ndarray 타입이 아닌, int32 타입임을 확인할 수 있다.

 

 

 

 

[ 추가 ]

인덱스에서 마이너스 기호를 이용하면, 맨 뒤에서부터 데이터를 추출할 수 있다.

ex) 인덱스 -1 : 맨 뒤의 데이터 값
      인덱스 -2 : 맨 뒤에서 두번째 데이터 값

 

 

 

 

 

 

 

또한 아래의 예시와 같이 단일 인덱스를 이용하여,

 

ndarray의 데이터 값을 수정할 수 있다.

 

 

 

 

 

 

 

다음으로 다차원 ndarray 에서 단일 값을 추출하는 방법을 알아보자.

 

 

 

 

다차원 ndarray의 경우,
콤마(,)로 분리된 row 와 column의 위치의 인덱스를 통해 접근한다.

 

 

 

 

아래의 예시를 통해 확인해보자.

 

 

 

 

 

 

 

- 3개의 row 각각에 0,1,2 인덱스로 / 3개의 column 에 0,1,2 인덱스가 부여

 

- array2d[0,0] : 첫 번째 row, 첫 번째 column 위치의 데이터인 1 추출

 

- array2d[0,1] : 첫 번째 row, 두 번째 column 위치의 데이터인 2 추출

 

- array2d[1,0] : 두 번째 row, 첫 번째 column 위치의 데이터인 4 추출

 

- array2d[2,2] : 세 번째 row, 세 번째 column 위치의 데이터인 9 추출

 

 

 

 

이때 앞에서 지칭한 row 와 column은 이해를 돕기 위한 표현일 뿐, 실제 ndarray 에서는 사용되지 않는다.

ndarray에서는 axis0 이 row, axis1이 column을 의미한다.
axis가 생략된 경우는 axis0을 의미한다.

ex) array2d[0,1] 값은 axis0 = 0, axis1 = 1 로 표기

( * 3차원의 경우 axis0, axis1, axis2 로 표기 (각각 행, 열, 높이))

 

 

 

 

 

 

2. 슬라이싱 (Slicing)

 

 

- 연속된 인덱스 상의 ndarray 추출하는 방식

 

- ' : ' 기호 사이에 시작 인덱스와 종료 인덱스를 표시

 

- (시작 인덱스)부터 (종료 인덱스 - 1) 위치에 있는 데이터 값 반환 

 

 

 

 

먼저 1차원 ndarray 에서의 예제를 살펴보자.

 

 

 

 

 

 

array1[0:3] 이므로 인덱스 0번 부터 인덱스 2번에 해당하는

 

1,2,3 데이터가 ndarray 형태로 추출된 것을 확인할 수 있다.

 

 

 

[ 추가 ]

슬라이싱 기호 ' : ' 사이의 시작, 종료 인덱스는 생략 가능하다.

1) 시작 인덱스 생략한 경우 : 자동으로 맨 처음 인덱스인 0부터 시작
2) 종료 인덱스 생략한 경우 : 자동으로 맨 마지막 인덱스에서 마침
3) 시작, 종료 인덱스 모두 생략한 경우 : 자동으로 맨 처음부터 맨 마지막 인덱스로 간주

 

 

 

 

 

 

 

 

다음으로 다차원 ndarray 에서의 예제를 살펴보자.

 

 

 

다차원 ndarray 에서는 1차원 ndarray 방식과 유사하지만,

 

콤마(,) 로 row와 column 인덱스를 선택한다.

 

 

 

 

 

 

 

첫 번째 예시를 살펴보자.

 

 

array2d[0:2, 0:2] 의 경우 row가 0~1, column이 0~1 인 데이터를 추출하는 것이다.

 

따라서 [1, 2] 와 [4, 5] 가 추출되는 것을 확인할 수 있다.

 

 

 

 

array2d[:2 , 0] 과 같이 뒤에 오는 인덱스를 0으로 설정하는 경우,

 

[1, 4] 와 같은 1차원 ndarray 의 값을 반환하게 된다.

 

( 3차원 ndarray 의 경우 2차원 ndarray 를 반환한다.) 

 

 

 

 

 

 

 

 

 

 

3. 팬시 인덱싱 (Fancy Indexing)

 

 

- 일정 인덱싱 집합을 리스트, ndarray 형태로 지정하여 반환

 

 

 

 

아래의 코드를 통해 2차원 ndarray에서 팬시 인덱싱을 적용한 예를 살펴보자.

 

 

 

 

 

 

array2d[[0,1], 2] 의 경우

 

 

- row 축의 팬시 인덱싱을 [0,1] 로, column 축은 단일 인덱싱 2를 사용

 

- (row, column) 인덱스가 (0,2), (1,2) 로 적용

 

- [3,6] 반환

 

 

 

array2d[[0,1], 0:2] 의 경우

 

 

- ( (0,0), (0,1) ), ( (1,0), (1,1) ) 인덱싱 적용

 

- [ [1,2], [4,5] ] 반환

 

 

 

array2d[[0,1]] 의 경우

 

 

- ( (0, : ), (1, : ) ) 인덱싱 적용

 

- [ [1,2,3], [4,5,6] ] 반환

 

 

 

 

 

마지막으로, 조건 필터링과 검색을 동시에 할 수 있는 인덱싱 방법을 살펴보자.

 

 

 

 

 

 

4. 불린 인덱싱 (Boolean Indexing)

 

 

- 특정 조건 해당 여부인 True / False 값 인덱싱 집합을 바탕으로 True 에 해당되는 데이터 ndarray 반환 

 

- 조건과 검색 기능을 수행하므로, 매우 자주 사용됨

 

 

 

 

 

예를 들어 [1,2,3,4,5,6,7,8,9] 에서 데이터 값이 5 이상인 데이터만 추출한다고 가정해보자.

 

원래는 for loop 을 돌면서 (데이터 값) > 5 인 데이터를 하나씩 찾아야 할 것이다.

 

 

 

하지만 불린 인덱싱을 사용하면,

 

ndarray 의 [ ] 내에 조건문을 입력하여 인덱싱을 적용할 수 있다.

 

 

 

아래의 예시를 살펴보자.

 

 

 

 

 

 

 

array1d = [1,2,3,4,5,6,7,8,9] 에서 5 이상의 값인,

 

[6,7,8,9] 가 추출된 것을 확인할 수 있다.

 

 

 

 

 

그렇다면 어떻게 이렇게 간단하게 조건 필터링이 가능한 것일까?

 

 

 

 

 

 

 

위의 예시를 살펴보면 array1d > 5 와 같이 ndarray 객체에 조건식을 붙이면,

 

True, False 로 이루어진 ndarray 객체가 반환되는 것을 확인할 수 있다.

 

 

 

output을 확인해 보면 해당 조건 식을 입력했을 때,

 

5보다 큰 데이터 값은 True, 5보다 작은 데이터 값은 False 값이 반환된다.

 

 

 

 

즉, ndarray 객체의 [ ] 내에 조건을 입력하면,
조건으로 반환된 False 값은 무시한 후, True 값이 있는 위치 인덱스 값을 자동 변환하여 데이터를 반환한다.

 

 

 

 

아래의 예시를 살펴보자.

 

 

 

 

 

 

실제로 ndarray1 > 5 와 동일한 불린 ndarray를 생성하고,

 

이를 ndarray1[ ] 내에 작성하여 필터링하면

 

동일한 결과인 [6,7,8,9] 가 출력되는 것을 확인할 수 있다.

 

 

 

 

 

 

 

이는 위의 예시처럼 직접 인덱스 집합을 만들고 대입한 것과 동일하다.

 

 

이때, np.array[ ] 내의 5,6,7,8 은 index 값을 의미하므로 0부터 시작한다.

 

6,7,8,9라고 쓰지 않도록 유의하자!

 

 

 

 

[ 불린 인덱싱 정리 ]

1) ndarray 의 [ ] 내에 필터링 하고자 하는 조건을 입력
2) False 값은 무시하고, True 값에 해당되는 인덱스 값만 저장 (True 값 자체가 아닌, True 값을 가진 인덱스 저장)
3) 저장된 인덱스 세트로 ndarray 조회

 

 

 

 


 

 

 

1.3.7 행렬의 정렬 - sort() 와 argsort()

 

 

 

넘파이에서 행렬을 정렬하는 대표적인 방법을 알아보자.

 

 

 

1. sort() : 행렬 정렬

 

 

 

1) 넘파이에서 행렬을 호출하는 방법 : np.sort()

 

 

- 원본 행렬은 그대로 유지한 채, 새롭게 정렬된 행렬을 반환

 

- 오름차순으로 행렬을 전환

 

- 내림차순으로 전환 시 np.sort()[::-1] 사용

 

 

 

 

 

 

 

 

2) 행렬 자체에서 호출하는 방법 : ndarray.sort()

 

 

- 원본 행렬 자체를 정렬된 행렬로 변환 후 반환

 

- 이때 새롭게 변환된 행렬의 반환 값은 None

 

- 오름차순으로 행렬을 전환

 

 

 

 

 

 

 

 

다차원 행렬의 경우,

 

axis 축 값을 사용하여 row(axios=0) 와 column(axis=1) 정렬을 수행할 수 있다.

 

 

 

 

 

 

 

 

 

2. argsort() : 정렬된 행렬의 인덱스를 반환하기

 

 

 

- np.argsort() 사용

 

- 원본 행렬이 정렬되었을 때, 기존의 원본 행렬에 대한 인덱스 반환

 

- 정렬된 행렬의 원본 행렬 인덱스를 ndarray 형태로 반환

 

- 기본적으로 오름차순 정렬

 

- 내림차순 정렬 시에 np.argsort(ndarray이름)[::-1] 적용

 

 

 

 

 

예시 코드를 확인해보면 다음과 같다.

 

 

 

 

 

 

원본 행렬 [3,1,9,5] 의 경우

 

(데이터 3 : 인덱스 0), (데이터 1 : 인덱스 1), (데이터 9 : 인덱스2), (데이터 5 : 인덱스 3)

값을 가지고 있다.

 

 

이때 행렬을 정렬하면 [1,3,5,9] 가 되므로,

 

(데이터1 : 인덱스1), (데이터3 : 인덱스 0), (데이터5 : 인덱스3), (데이터9 : 인덱스2) 가 되어

 

[1,0,3,2] ndarray가 반환된다.

 

 

 

 

 

이때 argsort()는 메타 데이터를 가질 수 없다!

따라서 메타데이터는 별도의 ndarray로 각각 가지고 있어야 한다.

 

 

 

 

아래의 예시를 통해 살펴보자.

 

 

 

 

 

 

학생 이름과 각 학생의 성적을 저장하고자 한다면,

 

이름과 성적을 각각 ndarray 2개로 저장해야 한다.

 

 

 

이때 성적 순으로 학생 이름을 확인하고 싶다면,

 

정렬된 인덱스를 name_array에 팬시 인덱스로 슬라이싱하여 추출할 수 있다.

 

 

 

 

 


 

 

 

1.3.8 선형대수 연산 - 행렬 내적과 전치 행렬 구하기

 

 

 

넘파이가 지원하는 다양한 선형대수 연산 중,

 

가장 기본적이고 많이 사용되는 '행렬 내적' 과 '전치 행렬' 을 구하는 방법을 알아보자.

 

 

 

 

1. 행렬 내적 (행렬 곱)

 

 

- 행렬 내적은 행렬 A의 row(행) 과 행렬 B의 column(열) 원소를 순차적으로 곱한 뒤, 그 결과 값을 모두 더한 값

 

- np.dot(A, B) 를 사용하여 행렬 내적 수행

 

 

 

 

아래의 예시를 통해 확인해보자. 

 

 

 

 

 

 

 

첫 번째 결과 값인 56의 경우만 살펴보자.

 

 

행렬 A의 row에 해당되는 [1,2,3] 과 행렬 B의 column에 해당되는 [7,9,11]을 하나씩 곱한 후 그 결과 값을 더해준다.

 

(1*7) + (2*9) + (3*11) = 58 이 된다.

 

 

np.dot()를 사용하면, 이 과정을 반복하여 행렬 내적 값을 반환하는 것을 확인할 수 있다.

 

 

 

 

 

2. 전치 행렬

 

 

- 전치 행렬은 원본 행렬에서 행과 열의 위치를 교환한 행렬

 

- 행렬 A의 전치행렬은 A^T로 표기

 

- transpose()를 사용하여 전치 행렬 수행

 

 

 

 

 

아래의 예시를 통해 확인해보자. 

 

 

 

 

 

 

원래 1행 2열에 해당되었던 '2' 와 2행 1열에 해당되었던 '3' 원소가 서로 교환된 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

권철민 '파이썬 머신러닝 완벽 가이드 (개정2판)' 책을 기반으로 작성하였습니다.