각자 파이썬을 공부하기 시작한 이유는 여러 가지가 있을 것이다.
프로그래밍을 처음 배우는 사람이 접하기 쉬운, 간편하면서 강력한 언어이기 때문일 수도 있고,
간단한 스크립트를 작성하여 자동화를 돌리고자 하는 사람도 있을 것이다.
또 Django 프레임워크를 이용해 웹 개발을 하고자 하는 사람도 있을 거라고 생각한다.
하지만 파이썬의 또 강력한 점은 데이터를 분석하고자 할 때 다양한 모듈들을 지원하기 때문에
데이터 과학과 머신러닝을 하는 것에 있어서 적합하다는 점일 것이다.
이번 장에서는 넘파이를 이용해 데이터 과학을 공부하는데 있어서
더욱 편리하게 할 수 있도록 공부해보고자 한다.
앞서서 이미 파이썬의 리스트에 대해서 공부해보았다.
하지만 데이터 과학에서 파이썬의 기본 리스트로 충분하지 않은 경우가 있다.
데이터를 처리할 때 리스트와 리스트 간의 다양한 연산이 필요한데
파이썬의 기본 리스트는 이러한 기능이 부족하기도 하고,
리스트를 다루는 일은 연산 속도도 그리 빠르지 않다.
이에 우리는 넘파이를 배워 다양한 데이터를 더 잘 다루고 처리속도를 높여보고자 한다.
넘파이는 대용량의 배열과 행렬 연산을 빠르게 수행하고,
고차원적인 수학 연산자와 함수를 포함하고 있는 라이브러리이다.
수치 데이터를 다루는 가장 기본적이고 강력한 패키지라 할 수 있다.
데이터 분석을 하기 위한 패키지인 Pandas 나 기계학습을 위한 Scikit-learn 이나
Tensorflow 등이 넘파이 위에서 동작하기 때문이다.
Pandas에 대해선 아래 글을 참고.
Tensorflow에 대해선 아래 글을 참고.
넘파이를 많이 사용하는 이유가 무엇일까?
넘파이는 성능이 우수한 ndarray 객체를 제공한다.
ndarray 란 n차원 배열을 의미한다.
"배열 array" 이란 동일한 자료형을 가진 데이터를 연속으로 저장한다.
ndarray 객체가 가진 장점은 아래와 같다.
- ndarray 는 C 언어에 기반한 배열 구조이므로 메모리를 적게 차지하고 속도가 빠르다
- ndarray 를 사용하면 배열과 배열 간에 수학적인 연산을 적용할 수 있다.
- ndarray 는 고급 연산자와 풍부한 함수들을 제공한다.
넘파이 배열을 간단한 예제를 통해 알아보자.
다음과 같이 학생 3명의 중간고사와 기말고사 성적을 저장하고 있는 리스트가 있다고 하자.
mid_score = [10, 20, 30]
final_score = [70, 80, 90]
우리는 다음 표와 같이 각 학생들의 중간고사 성적과 기말고사 성적을 합하여
오른쪽의 total(총점) 이라는 리스트를 만들고 싶다.
중간고사 | 기말고사 | 총점 | |
학생 1 | 10 | 70 | 80 |
학생 2 | 20 | 80 | 100 |
학생 3 | 30 | 90 | 120 |
그런데, 파이썬의 리스트에서 더하기 연산자는 두 리스트를 연결하므로,
mid_score + final_score 를 이용하면 다음과 같이 2개의 리스트를 연결한 리스트가 만들어진다.
mid_score = [10, 20, 30]
final_score = [70, 80, 90]
total = mid_score + final_score
print(total)
# [10, 20, 30, 70, 80, 90]
하지만 넘파이 배열에 + 연산을 하면, 대응되는 값끼리 합쳐진 결과를 얻을 수 있다.
넘파이를 사용하기 위해서는 import numpy as np 를 이용해 넘파이 패키지를 불러와야 한다.
뒤에 as np 라고 붙은 것은, numpy 를 np 라는 "별칭 alias" 으로 부르겠다는 뜻이다.
이제 넘파이 배열을 만들어보자.
넘파이 배열을 만들기 위해서는 넘파이가 제공하는 array() 함수를 사용한다.
array() 함수에 파이썬 리스트를 전달하면 넘파이 배열이 생성된다.
import numpy as np
mid_score = np.array([10, 20, 30])
final_score = np.array([70, 80, 90])
2개의 배열을 합하여 학생들의 총점을 계산해보자.
ndarray 의 덧셈 연산을 수행하면 된다.
import numpy as np
mid_score = np.array([10, 20, 30])
final_score = np.array([70, 80, 90])
total = mid_score + final_score
print('시험 성적의 합계 :', total) # 시험 성적의 합계 : [ 80 100 120]
print('시험 성적의 평균 :', total/2) # 시험 성적의 평균 : [40. 50. 60.]
위와 같이 넘파이는 배열 요소별로 지정된 연산을 수행할 수 있다.
이번에는 넘파이의 핵심이 되는 다차원 배열에 대해서 알아보자.
다차원 배열 ndarray 는 다음과 같은 속성을 가지고 있다.
속성 | 설명 |
ndim | 배열 축 혹은 차원의 개수 |
shape | 배열의 차원으로 (m, n) 형식의 튜플 형. 이때 m과 n은 각 차원의 원소 크기를 알려주는 정수 |
size | 배열 원소의 개수. 이 개수는 shape 내의 원소 크기의 곱과 같다. 즉 (m, n) 형태 배월의 size 는 mxn 이다. |
dtype | 배열 내의 원소의 형을 기술하는 객체. 넘파이는 파이썬 표준 자료형을 사용할 수 있으나 넘파이 자체의 자료형인 bool_, character, int_, int8, int16,,, float, float8, float16,,, 등을 사용할 수 있다. |
itemsize | 배열 내의 원소 크기를 바이트 단위로 기술. 예를 들어 int32 자료형의 크기는 32 / 8 = 4 바이트가 된다. |
data | 배열의 실제 원소를 포함하고 있는 버퍼 |
stride | 배열 각 차원별로 다음 요소로 점프하는 데에 필요한 거리를 바이트로 표시한 값을 모은 튜플 |
다음 예제를 통해 ndarray 객체를 생성하고 속성을 알아보자.
1. 0에서 9까지의 정수 값을 가지는 ndarray 객체 array_a 를 넘파이를 이용, 작성하여 내용을 출력하자.
2. range() 함수를 사용하여 0에서 9까지의 정수 값을 가지는 ndarray 객체 array_b 를 만들고
아래의 결과와 같이 나타나도록 하자.
3. 문제 2의 코드를 수정하여 0에서 9까지의 정수 값 중에서 다음과 같이 짝수를 가지는 ndarray 객체
array_c 를 생성하자.
4. array_c 의 shape, ndim, dtype, size, itemsize 를 출력하자.
결과화면은 아래와 같다.
넘파이 배열을 만드는 방법은 넘파이의 array() 메소드에 리스트를 넘겨주면 된다.
그러면 해답 코드를 한 번 보자.
import numpy as np
# 실습 1
array_a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print('실습 1 : array_a =', array_a)
# 실습 2
array_b = np.array(range(10))
print('실습 2 : array_b =', array_b)
# 실습 3
array_c = np.array(range(0,10,2))
print('실습 3 : array_c =', array_c)
# 실습 4
print('실습 4: ')
print('array_c의 shape :', array_c.shape)
print('array_c의 ndim :', array_c.ndim)
print('array_c의 dtype :', array_c.dtype)
print('array_c의 size :', array_c.size)
print('array_c의 itemsize :',array_c.itemsize)
넘파이 배열에는 + 연산자나 * 연산자와 같은 수학적 연산자를 얼마든지 적용할 수 있다.
예를 들어 회사가 좋은 성과를 거두어 전 직원의 월급을 100만원씩 올려주기로 했다.
이를 넘파이 배열을 이용해 어떻게 하면 간단하게 처리할 수 있을까?
현재 직원들의 월급이 [220, 250, 230] 이라고 하자.
import numpy as np
salary = np.array([220, 250, 230])
salary = salary + 100
print(salary)
# [320 350 330]
위와 같이 코드를 작성하면 되겠다.
넘파이 배열에 저장된 모든 값에 100을 더하려면
넘파이 배열 salary 에 100을 더해주면 끝이다.
그렇다면 사장의 기분이 좋아져 월급을 두 배로 올려주려면 어떻게 하면 될까?
salary = salary * 2
print(salary)
# [440 500 460]
위와 같이 넘파이 배열에 2를 곱해주면 전체 값이 2배가 되는 것을 확인할 수 있다.
파이썬의 기본 리스트에는 리스트와 리스트 간의 연산이 정의되어 있지 않다.
따라서 요소별로 대응시켜 계산하는 일을 할 때에는
넘파이의 다차원 배열 ndarray 를 이용하면 된다.
넘파이 배열에서는 리스트에서 했던 것과 같이 인덱싱과 슬라이싱 역시 동일하게 할 수 있다.
그럼 이번엔 2차원 배열을 다루어보자.
이름이 "다차원 배열" 인 것에서 알 수 있듯이 넘파이를 사용하면
2차원 배열도 쉽게 만들 수 있다.
앞에서와 마찬가지로 파이썬의 2차원 리스트를 먼저 생성한 후에
이것을 넘파이의 2차원 배열로 변경하면 된다.
2차원 리스트는 리스트 안에 다른 리스트가 들어있는 형태로,
수학에서의 행렬 matrix 과 비슷하다.
(하지만 리스트는 행렬 연산을 지원하지 않는다.)
import numpy as np
matrix_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix_array)
다음과 같이 2차원 배열을 만들면 수학에서의 행렬과 같이 다룰 수 있다.
2차원 배열에서 특정한 위치에 있는 요소는 역시 인덱스를 사용하면 된다.
다만 2차원이기 때문에 인덱스가 2개 필요하다.
첫 번째 인덱스는 행의 번호이고, 두 번째 인덱스는 열의 번호이다.
예를 들어 위 코드에서 matrix_array[0][2] 는 3이 된다.
하지만 넘파이에서는 많이 사용되는 표기법이 있다.
위의 표현을 matrix_array[0, 2] 로 고쳐 사용하면 된다.
2차원 넘파이 배열은 "행렬" 이다.
행렬에서는 행의 번호와 열의 번호만 있으면 특정한 요소를 꺼낼 수 있다.
따라서 넘파이 스타일로 [row, col] 인덱스를 사용하면 row 행을 가져온 뒤에
col 번째 항목을 찾는 것이 아니라 특정 항목에 바로 접근하게 된다.
역시나 슬라이싱을 이해하기 위해 예제를 하나 살펴보자.
특정 조건을 만족하는 행만을 추출해내보자.
선수드르이 키와 몸무게가 하나의 리스트를 구성하고 있고,
또 이들의 리스트로 이루어진 데이터 player 가 있다고 가정하자.
players = [[170, 76.4],
[183, 86.2],
[181, 78.5],
[176, 80.1]]
이것을 바탕으로 넘파이 2차원 배열을 만들어 보고, 선수들 가운데 몸무게가 80을 넘는 선수들만 골라서
정보를 출력해 보자. 또 키가 180 이상인 선수들의 정보도 추출해보자.
결과화면은 다음과 같이 나오게 하자.
고민하면서 코딩 해보았다고 믿겠다.
이제 해답코드를 보자.
import numpy as np
players = [[170, 76.4],
[183, 86.2],
[181, 78.5],
[176, 80.1]]
np_players = np.array(players)
print('몸무게가 80 이상인 선수 정보')
print(np_players[ np_players[:, 1] >= 80.0 ])
print('키가 180 이상인 선수 정보')
print(np_players[ np_players[:, 0] >= 180.0 ])
players 2차원 리스트를 넘파이 배열로 바꾼다.
몸무게가 80 이상인 선수를 찾을 때 np_players[ np_players >= 80.0 ]
이렇게 진행하면 어떤 문제가 생길까?
이 코드는 각 항목별 검사를 통해 80 이상인 데이터는 모두 추출하여 1차원 배열을 만든다.
그러면 키와 몸무게의 구분이 사라져 버린다.
우리는 몸무게를 검사해서 조건을 만족하는 행을 추출해 내야 하기 때문에
np_players[ np_players[:, 1] >= 80.0 ] 이런 식으로 코드를 구성해야 한다.
이번 장에서는 넘파이를 이용해 다차원 데이터를 쉽게 다루는 것을 공부해보았다.
넘파이 배열을 이용하면 행렬처럼 다룰 수 있고, 배열끼리의 연산이 가능하기에
편리하게 사용할 수 있다. 넘파이 배열의 아주 겉부분만 훑어보았다.
앞으로 넘파이를 많이 사용하고 평균값도 계산해보고, 상관관계도 살펴보면서
여러가지를 공부해보면 좋겠다.
출처 : 따라하며 배우는 파이썬과 데이터 과학 - 천인국, 박동규, 강영민