※ 이 포스팅은 저자 'Kirthi Raman'의 도서 <Mastering Python Data Visualization> 을 공부하며 정리한 글입니다.
Chapter 04-1. Numerical Computing (수치 연산)
NumPy, SciPy 라이브러리
이들은 파이썬 계산 모듈로서, 함수들이 미리 컴파일 되어있어 빠르게 수행된다.
NumPy는 많은 양의 수치 데이터를 다루기 위한 것이며, SciPy는 응용 수학 부문의 유용한 알고리즘을 제공하는 NumPy의 확장판이다.
#. Interpolation (보간)
- NumPy의 interp() 함수
#. Vectorization 기능
- NumPy와 SciPy에서 vectorize()는 함수를 벡터화하여 효율적인 작업을 가능하게 한다.
- 즉, vectorize()는 스칼라 값을 인수로 받는 함수를 배열도 인수로 사용되도록 하는 기능이다.
#. NumPy 선형 대수
- dot(a,b) : 두 배열의 내적
- linspace(a,b,n) : a부터 b의 범위에서 n개의 수를 생성
- diff(x) : 미분
- linalg.norm(x) : 행렬이나 벡터의 노말
- linalg.cond(x) : 조건 수
- linalg.solve(A, b) : Ax=b의 솔루션
- linalg.inv(A) : 역행렬
- linalg.pinv(A) : 역행렬
- linalg.eig(A) : 제곱의 고유/벡터값
- linalg.eigval(A) : 고유값
- linalg.svd(A) : 단수 값 분해
#. SciPy의 함수
- spio.loadmat : 행렬 로드
- spio.savemat : 행렬 저장
- scio.imread : 이미지 로드
- scipy.polyid : 다항식을 정의하여 여러 편리한 계산이 가능하도록 도움.
* 등 많은 것이 이미 SciPy에 구현되어 있으므로, 파이썬으로 계산 프로그램을 개발할 때 의도한 기능 관련하여 먼저 개발 문서를 확인해보자.
- scipy.cluster : 벡터 양자화, K-means 등 클러스터링
- scipy.fftpack : 고속 푸리에 변환
- scipy.integrate : trapezoidal(사다리꼴), Simpson's, Romberg 등의 방법으로 적분 수행.
quad, dblquad, tplquad 함수로 객체에 싱글, 더블, 트리플 통합 수행 가능.
- scipy.interpolate : 분리된 수치 데이터와 선형 또는 spline interpolation(보간) 개체 함수와 클래스
- scipy.linalg : NumPy의 linalg 패키지를 위한 wrapper. 모든 NumPy 함수들은 scipy.linalg의 일부임.
- scipy.optimize : Neider-Mead Simplex, Powell, 결합 그라데이션 BFGS, 최소 제곱, 제약 최적화, 시뮬레이션 annealing, Newton's Method, 이분법, Broyden Anderson, Linear Search 등을 통한 최대값과 최소값 등을 찾는 기능.
- scipy.sparse : Sparse matrices 관련
- scipy.special : 타원, 베셀, 감마, 베타 초기화, 포물선, 실린더, Mathieu 및 회전 타원체 파도와 같은 계산 물리 위한 특수 함수
MKL 함수
인텔이 개발한 벡터와 행렬에 대한 고성능 처리를 지원하는 함수이다.
FFT 함수와 벡터 통계 함수도 포함되어있다.
인텔 프로세서(CPU)에서 효율적으로 동작하도록 최적화 되어있다.
아나콘다 사용자들은 아나콘다 가속 패키지 일부의 애드온으로 이용 가능하다.
파이썬의 성능 이슈
종종 파이썬의 성능 이슈로 인해 C 언어로 프로그램을 다시 작성하거나, 컴파일된 C 함수들을 호출하는 일이 있다.
Cython처럼 더 쉽게 최적화를 하기 위한 목적의 많은 프로젝트들이 있으나, 기존 파이썬 코드를 효율적으로(빠르게) 만드는 것이 좋다.
#. Numbapro
- 파이썬 코드를 CUDA 가능 CPUs나 멀티코어 CPU, 또는 GPU에서 수행하도록 만드는 Continuum Analytics의 파이썬 컴파일러이다.
- 런타임에 just-in-time(JIT) 컴파일 된다.
- 상업 라이센스임에 유의
#. Scipy.weave
- C 코드를 중간에 삽입, NumPy 배열을 C 층으로 자연스럽게 이동시켜주는 모듈. 효율적인 메크로를 가지고 있다.
#. 멀티코어 활용
#. 프로세스 Pool 활용
- Pool은 멀티프로세싱의 패키지에 또 다른 클래스이다.
- Pool 안에 생성도니 프로세스 수를 정의할 수 있으며 각 프로세스에게 전달될 파라미터를 가지고 있는 반복 객체를 보낼 수 있다.
#. Disco 등 분산 계산 패키지 활용
- MapReduce 패러다임 기반 가벼운 오픈소스 프레임워크
- 이 외 Hadoop Streaming, mrjob, dumbo, hadoopy, pydoop 등이 있다.
분할(Slicing)
배열은 리스트나 튜플로 분할될 수 있다.
[ : , : , ... : ] 와 같은 문법을 사용한다.
#. :and: == 0:n:0
#. m: , m:n: == m:n:1
#. :n: == 0:n:1
#. ::d: == 0:n:d
#. 예시
>>> x = numpy.array([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])
>>> x[:2] # 0 ~ 2 까지
array([5, 6])
>>> x[::2] # 0 ~ n 까지 2 스탭
array([5, 7, 9, 11, 13, 15, 17, 19])
#. 행렬의 분할
>>> a = numpy.array([ [4,5,6], [7,8,9], [1,2,3] ])
>>> a
array([[4, 5, 6],
[7, 8, 9],
[1, 2, 3]])
>>> a.flat[:]
array([4, 5, 6, 7, 8, 9, 1, 2, 3])
색인(Indexing)
#. 수치 색인
- 정수 데이터를 가진 리스트로 Indexing 할 수 있다.
>>> a = 10 * numpy.arange(5.0)
>>> a
array([0., 10., 20., 30., 40.])
>>> a[1] # 값을 반환
10.0
>>> a[[1]] # 배열을 반환
array([10.])
>>> sel = numpy.array([3,1,4,2,3,3])
>>> a[sel] # 위치를 반복하여 배열로 반환할 수 있다
array([ 30., 10., 40., 20., 30., 30.])
>>> sel = numpy.array([[4,1], [3,2]])
>>> sel # 2차원에서도 가능
array([[4, 1],
[3, 2]])
>>> a[sel]
array([[ 40., 10.],
[ 30., 20.]])
#. 논리 색인
- 전등 스위치와 같이, 참이거나 거짓인 조건을 활용할 수 있다.
>>> x = numpy.arange(-4, 5)
>>> x
array([-4, -3, -2, -1, 0, 1, 2, 3, 4])
>>> x < 0
array([ True, True, True, True, False, False, False, False, False], dtype=bool)
>>> x[x>0]
array([1, 2, 3, 4])
>>> x[abs(x) >= 2]
array([-4, -3, -2, 2, 3, 4])
>>> x = numpy.reshape(numpy.arange(-8, 8), (4, 4)) # 2차원 예시
>>> x
array([[-8, -7, -6, -5],
[-4, -3, -2, -1],
[ 0, 1, 2, 3],
[ 4, 5, 6, 7]])
>>> x[x<0]
array([-8, -7, -6, -5, -4, -3, -2, -1])
>>> from math import isnan # 여러 방식의 논리 색인
>>> list1 = [[3, 4, float('NaN')],
[5, 9, 8],
[3, 3, 2],
[9, -1, float('NaN')]]
>>> [elem for elem in list1
if not any([isnan(element) for element in elem])]
[[5, 9, 8], [3, 3, 2]]
>>> list2 = [3,4,5,6]
>>> [list2[index] for index, elem in enumerate(list1)
if not any([isnan(element) for element in elem])]
[4, 5]
파이썬의 다양한 데이터 구조
파이썬은 스택, 리스트, 집합(Set), 시퀀스, 튜플, 리스트, 힙, 배열, 사전(Dictionary), 디큐(Dequeue) 등의 데이터 구조를 가진다.
참고로, 튜플은 불변성으로 리스트보다 더 효율적인 메모리 효율을 갖는다.
#. 스택(Stack)
- list() 함수는 스택으로서 사용되기 유용하다.
- 새로 들오온 요소는 뒤로 추가되고, 가장 먼저 들어온 것이 먼저 나가는(선입선출) 실행 원칙을 가진 추상 데이터 유형이다.
- append()로 아이템을 추가한다.
- pop()으로 아이템을 추출한다.
- remove(item-value)로 아이템을 제거한다.
#. 튜플(Tuple)
- 불변하는 오브젝트의 시퀀스이다. 따라서 오브젝트를 바꿀 수도, 제거할 수도 없다. 하지만 튜플 자체(오브젝트 전체)를 지우는 것은 가능하다.
- 다원화된 데이터 구조를 갖는다.
- 리스트가 같은 요소들의 시퀀스인 반면, 튜플은 요소들이 서로 다른 의미를 가진다.
- 리스트는 시퀀스를 갖고, 튜플은 구조를 갖는다.
- 튜플의 예는 한 주의 요일, 강의의 과목 이름, 등급 척도 등이다.
- del tuble-name 으로 튜플을 지운다.
- cmp(tup1, tup2) : 튜플의 요소를 비교
- len(tuple) : 전체 길이
- max(tuple) : 요소들의 최댓값
- min(tuple) : 요소들의 최솟값
- tuple(lista) : 리스트를 튜플로 변환
- 참고로, 파이썬은 max() 함수에 문자열의 리스트를 입력하면 가장 긴 문자열을 return한다. (min() 함수도 마찬가지)
#. 셋(Set)
- 리스트와 유사하나, 순서가 없는 집합이다. 리스트는 위치나 색인에 의해 순서화된다.
- 중복을 허용하지 않는다. (중복이 없다)
#. 사전(Dictionary)
- 키와 값의 쌍으로 구성된, 순서가 없는 데이터 값들의 집합
- 색인으로서 키를 기반으로 값에 접근할 수 있는 장점이 있다.
- 디폴트 사전(Default Dictionary)은 키와 값의 쌍이 삽입된 순서를 유지하지 않는다. OrderedDict() 함수로 생성된 빈 사전은 순서를 유지한다.
>>> # 예제 1 : 아프리카의 10대 GDP
>>> gdp_dict = {
'South Africa': 285.4,
'Egypt': 188.4,
'Nigeria': 173,
'Algeria': 140.6,
'Morocco': 91.4,
'Angola': 75.5,
'Libya': 62.3,
'Tunisia': 39.6,
'Kenya': 29.4,
'Ethiopia': 28.5,
'Ghana': 26.2,
'cameron': 22.2
}
>>> gdp_dict['Angola']
75.5
( .. 다음 포스팅에 계속 .. )