-
파이썬 데이터사이언스 핸드북 2 장 - NumPy 배열연산 ufuncs 소개데이터 분석/NumPy 2020. 5. 17. 18:51
NumPy 는 데이터 배열을 사용하여 최적화된 연산을 위한 쉽고 유연한 인터페이스를 제공한다.
NumPy 배열의 연산은 아주 빠르거나 아주 느릴 수 있다. 이 연산을 빠르게 만드는 핵심은 벡터화 (vectorized) 연산을 사용하는 것인데, 그것은 일반적으로 NumPy 의 유니버셜 함수 (universal functions, ufuncs) 를 통해 구현된다. 이번 절에서는 배열 요소에 대한 반복적인 계산을 더 효율적으로 수행하게 해주는 NumPy 의 ufuncs 의 필요성에 대해 생각해 보겠다. 그러고 나서 NumPy 패키지에서 사용할 수 있는 가장 보편적이면서 유용한 여러 산술 유니버설 함수를 소개한다.
compute_reciprocals(big_array)
여기서 병목은 연산 자체에 있는 것이 아니라, CPython 이 루프의 싸이클마다 수행해야 하는 타입 확인과 함수 디스패치에서 발생한다. 역수가 계산될 때마다 파이썬은 먼저 객체의 타입을 확인하고 해당 타입에 맞게 사용할 적절한 함수를 동적으로 검색한다. 만얄 컴파일된 코드로 작업했다면 코드를 실행하기 전에 타입을 알았을 것이고 결과값은 좀 더 효율적으로 계산되었을 것이다.
1.0 / big_array
big_array 는 int 를 요소로 받는 배열이다. NumPy 는 여러 종류의 연산에 대해 이러한 종류의 정적 타입 체계를 가진 컴파일된 루틴에 편리한 인터페이스를 제공한다. 이를 벡터화 연산이라고 한다. 벡터화 연산은 간단한 배열에 연산을 수행해 각 요소에 적용함으로써 수행할 수 있다. 이 벡터화 방식은 루프를 NumPy 의 기저를 이루는 컴파일된 계층으로 밀어 넣음으로써 훨씬 빠르게 실행되도록 설계됐다.
0.002 sec 와 1.845 sec 의 차이를 만들어낸다. 이렇게나 다르다!
NumPy 유니버설 함수 ufuncs
ufuncs 는 배열간 또는 배열과 상수간 연산을 지원한다.
동일한 형태의 배열끼리 ufuncs 연산
각 위치에 있는 것들끼리 연산한다.
다른 형태의 배열끼리 ufuncs 연산
배열의 형태가 달라도 일부 케이스에 한해 ufunc 연산을 할 수도 있다.
- 차원이 동일하고, 연산대상 중 하나가 요소의 크기가 1이거나
- 연산대상의 요소의 크기가 같고, 연산대상 중 하나의 차원크기가 1이면 된다.
배열의 형태가 다르고, 위의 제약사항도 부합하지 않으면, ufuncs 연산이 실패한다.
배열과 상수 간의 ufuncs 연산
배열간 연산이 아니어도, 배열과 상수의 연산도 가능하다. 1차원 배열과 상수, 다차원 배열과 상수 모두 가능하다.
NumPy 연산
NumPy 산술연산
NumPy ufuncs 는 파이썬의 기본 산술 연산자를 사용하기 때문에 자연스럽게 사용할 수 있다. 표준 덧셈, 뺄셈, 곱셈, 나눗셈 모두를 사용할 수 있다. 물론 음수를 만드는 단항 unfucs 도 활용할 수 있다. 지수 연산자 **, 나머지 연산자 % 도 사용할 수 있다. 이 연산들은 원하는 만큼 함께 사용할 수 있으며, 표준 연산 순서를 따른다.
이 산술 연산은 모두 사용상 편의를 위해 NumPy 에 내장된 특정함수를 감싼 것이다. 예를 들어, + 연산자는 add 함수의 래퍼 (wrapper) 함수이다. NumPy 에서 가능한 산술 연산 리스트는 다음과 같다. (이렇게 많다.)
출처: https://docs.scipy.org/doc/numpy/reference/ufuncs.html
사용법은 쉬우니까 다해보지는 않았다. 상용 함수로 요런 것들이 있다.
- 음수/양수/절대값 함수 negative / positive / absolute
- 나머지 함수: remainder / mod / fmod / divmod
- 반올림 함수 rint
- 제곱값, 제곱근 함수 sqrt / square
- 지수와 로그 exp / exp2 / power / log / log2 / log10
- 매우 작은 입력값의 정확도를 유지할때 유용한 함수: expm1, log1p
다양한 연산 제공
**그 외에, 삼각함수 연산, 비트와이즈연산, 비교연산 등 다양한 연산방식을 제공한다.
ufuncs. element-wise
element-wise 는 피연산대상 배열의 각 요소값 끼리 연산함을 의미한다.
In mathematics, the Hadamard product (also known as the element-wise, entrywise[1]:ch. 5 or Schur[2] product) is a binary operation that takes two matrices of the same dimensions and produces another matrix of the same dimension as the operands where each element i, j is the product of elements i, j of the original two matrices. It should not be confused with the more common matrix product.
수학에서 Hadamard product, element-wise, entrywise, Schur Product라고 불리는 것은 같은 차원을 가진 행렬 2개에 대한 연산자로, 연산의 결과는 피연산자 (연산대상)과 동일한 차원의 행렬이 된다. 즉, i,j 위치에 있는 요소는 피연산자의 i,j 위치에 있는 요소에 대해 연산한 값이다. (2,3)(3,2) = (2,2) 와 같은 행렬 계산과는 다르다.
선형대수와 벡터 등 수학을 다시 공부해야하려나....ㅎ
'데이터 분석 > NumPy' 카테고리의 다른 글
파이썬 데이터사이언스 핸드북 2장 - Numpy 집계 (0) 2020.05.24 파이썬 데이터사이언스 핸드북 2 장 - NumPy 지수와 로그 함수 (0) 2020.05.23 파이썬 데이터사이언스 핸드북 2 장 - NumPy 배열의 기본 기능 (0) 2020.05.16 파이썬 데이터사이언스 핸드북 2 장 - ndarray 소개 (0) 2020.05.16 파이썬 데이터사이언스 핸드북 2장 - Numpy 소개 (0) 2020.05.12