https://wlalsu.tistory.com/110?category=670879
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판)' 책을 기반으로 작성하였습니다.
'[Capstone Study] 머신러닝 완벽 가이드' 카테고리의 다른 글
[머신러닝] 섹션 1.4 데이터 핸들링 - 판다스 (2) (0) | 2023.11.06 |
---|---|
[머신러닝] 섹션 1.4 데이터 핸들링 - 판다스 (1) (0) | 2023.11.06 |
[머신러닝] 섹션 1.3 넘파이 (1) (0) | 2023.09.21 |
[머신러닝] 섹션 1.2 파이썬 머신러닝 생태계를 구성하는 주요 패키지 (0) | 2023.09.21 |
[머신러닝] 섹션 1.1 머신러닝의 개념 (0) | 2023.09.21 |