파이썬 기반 데이터분석을 위하여 NumPy 라이브러리에 대해 간단하게 알아본다.
개요
파이썬의 경우 기본 함수만 사용할 경우 평균이나 분산 등 데이터 분석에 필요한 간단한 연산을 하기도 어렵다. 그래서 다양하고 전문적인 산술연산을 위해 각종 라이브러리의 도움을 받게 되는데 그 시작이 NumPy 라고 할 수 있다.
라이브러리 준비
설치
주피터 노트북 환경 기준으로 “pip”를 사용하여 설치할 수 있다.
※ 간혹 “--user” 를 요구하는 경우가 있다.
※ 하이픈 2개 “--“와 1개”-“를 잘 구분하도록 하자.
!pip install numpy
!pip install numpy --user
특정 버전을 설치하는 경우 다음과 같이 입력할 수 있다.
!pip install numpy==1.24.2
만약 설치시 에러가 발생한다면 다음의 코드로 해결이 될 수 있다.
!pip install --force-reinstall numpy==1.24.2
업데이트
최신의 라이브러리를 사용하고자 하는데 정확한 버전을 찾아보기 귀찮다면 다음과 같이 해결할 수 있다.
※ 하이픈 2개 “--“와 1개”-“를 잘 구분하도록 하자.
!pip install numpy --upgrade
만약 상기 코드 실행시 에러가 발생한다면 다음의 코드로 해결이 될 수 있다.
!pip install numpy --upgrade --ignore-installed
라이브러리 사용
설치가 성공적으로 되었다면 라이브러리를 불러올 수 있다. 여기서 불러온다는 것은 해당 라이브러리의 기능을 사용하도록 준비하는 것이라고 이해하면 된다. 그리고 경우에 따라 라이브러리 버전별 함수의 동작결과가 다를 수 있기 때문에 이 것을 확인하는 것도 종종 필요하다.
불러오기
1 | import numpy as np |
“NumPy” 로 대소문자를 섞어쓰는 것이 아닌 모두 소문자로 쓰면 되며 보다 간결한 코드 작성을 위해 “numpy” 대신 “np”로 선언하였다. 물론 “as” 뒤에 “np” 대신 다른 글자로 선언해도 되지만 NumPy의 경우 대부분의 사람들이 “np”로 선언하기 때문에 되도록이면 이를 지켜주는 것을 권장한다.
라이브러리를 불러오는 것은 한번 실시하면 다시 불러올 필요가 없다. 엄밀하게 말하면 단일 주피터 노트북에서 계속 작업하는 경우 노트북 재시작(의도치 않은 재시작 포함)이나 노트북 자체를 껐다가 켜는 경우가 아니라면 다시 “import numpy as np” 코드를 실행할 필요가 없다는 뜻이다.
버전 확인
NumPy 라이브러리를 “np”로 불러온 경우 “np” 뒤에 “__version__“(양 옆에 언더바 2개)을 써서 버전을 확인할 수 있다.
1 | import numpy as np |
함수의 사용
다음의 코드는 앞에서 NumPy 라이브러리를 “np”로 먼저 불러왔다는 전제하에 작성된 코드이기 때문에 이를 참고해서 코드를 따라 작성하면 되겠다. 그리고 드디어 파이썬에서 평균을 계산할 수 있다.
1 | np.mean([1, 2, 3, 4, 100]) |
물론 분산(variance)과 표준편차(standard deviation)도 계산 가능하다.
1 | np.var([1, 2, 3, 4, 100]) |
여기에 기본함수를 덧씌울 수도 있다.
1 | round(np.std([1, 2, 3, 4, 100]), 2) |
사실 NumPy의 경우 어레이(Array, 배열)이라는 전용 객체가 있지만 리스트 객체를 입력해도 어레이를 입력한 것 처럼 사용할 수 있다. 이제 어레이를 알아보자.
관련 객체
다차원의 복잡한 구조 구현이 가능한 객체로 리스트를 기반으로 생성하며 벡터연산과 행렬연산 뿐만아니라 다양한 수치연산까지 지원.
- 생성
array() 함수에 리스트 객체를 입력. 객체의 차원은 리스트 객체의 중첩수와 동일하며 2차원 객체의 경우 중첩된 리스트를 쉼표를 사용하여 행을 구분한다.
2차원 배열의 경우 특정 행에 할당되는 원소의 개수 또는 특정 열 할당되는 원소의 개수가 같아야 하며 특정 위치의 원소를 명시하지 않으려면 결측(missing) 표기를 사용해야한다.
※ np.nan
1 | np.array([1, 2]) |
조작
기본 행렬연산을 지원하며 각종 메서드를 활용하여 복잡한 산술연산 수행 가능하고 리스트 객체와는 달리 일부 원소를 추출할 때 이산 위치의 원소 또한 추출 가능하다. 추가로 특정 위치의 원소를 추출하는 것 뿐만 아니라 조건식을 사용한 필터링을 할 수 있다.주의
일부 또는 전체를 복제하는 경우 단순 데이터의 주소만 복사하는 “얕은 복사”와 데이터를 온전히 복사하는 “깊은 복사”의 동작에 유의할 것.
※ np.array.copy()
NumPy 라이브러리의 어레이 객체와 관련해서는 별도의 포스팅에서 다룰 예정이다.
유용한 함수
NumPy는 전문적인 선형대수 연산을 위해 사용하는 것이 아니라면 아주 일부의 함수만 숙지하는 것을 권장한다. 그래서 보편적인 데이터분석을 위해 상대적으로 자주 사용하는 함수는 다음과 같다.
np.arange()
: 수열 생성(시작, 끝, 증분 지정가능)1
2
3
4
5
6
7
8np.arange(4)
## array([0, 1, 2, 3])
np.arange(3, 6)
## array([3, 4, 5])
np.arange(5, 10, 2)
## array([5, 7, 9])np.r_[]
: 이산, 연속 수열 생성 가능1
2np.r_[1, 2, 5:9]
## array([1, 2, 5, 6, 7, 8])np.where()
: 엑셀의if()
함수, R의ifelse()
함수와 동일한 기능을 한다.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15arr = np.array([2, 4, 6, 8])
arr
## array([2, 4, 6, 8])
np.where(arr > 5, "A", "B")
## array(['B', 'B', 'A', 'A'], dtype='<U1')
np.where(arr < 5, 1, 0)
## array([1, 1, 0, 0])
np.where(arr > 5, "A", arr)
## array(['2', '4', 'A', 'A'], dtype='<U11')
np.where(arr > 5, arr, "B")
## array(['B', 'B', '6', '8'], dtype='<U11')np.exp()
: 밑이 오일러수(e)인 지수 연산. 향후 (이항)로지스틱 회귀분석의 승산비(OR) 계산에 사용한다.1
2
3
4
5np.exp(1)
## 2.718281828459045
np.exp(2)
## 7.38905609893065np.log()
: 자연로그1
2
3
4
5np.log(2)
## 0.6931471805599453
np.log(np.exp(1))
## 1.0np.log10()
: 상용로그1
2np.log10(100)
## 2.0