English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

NumPy ufunc 일반 함수

NumPy는 두 가지 기본 객체를 제공합니다.那就是 ndarray와 ufunc 객체. ufunc은 universal function의 약자로, '통용 함수'라는 의미로, 배열의 각 요소에 작용할 수 있는 함수입니다.
많은 ufunc 함수는 C 언어 수준에서 구현되었기 때문에 계산 속도가 매우 빠릅니다.
또한, ufun은 math 모듈의 함수보다 유연합니다. math 모듈의 입력은 일반적으로 스칼라이지만, NumPy의 함수는 벡터나 행렬이 될 수 있으며, 벡터나 행렬을 사용하면 루프 문을 사용하지 않을 수 있습니다. 이 점은 기계 학습, 깊은 학습에서 매우 중요합니다.

ufunc을 사용하는 이유는 무엇인가요?

ufunc은 NumPy에서 벡터화를 구현하는 데 사용되며, 요소 반복보다 훨씬 빠릅니다.
그들은 또한 방송 및 다른 방법, 예를 들어 감소, 누적 등을 제공하여 계산에 매우 유용합니다.
ufunc은 다른 매개변수도 받을 수 있습니다. 예를 들어:
where는 조건을 정의하여 어떤 곳에서 작업을 수행할지 지정합니다.
dtype는 요소의 반환 타입을 정의합니다.
out은 복사되어야 할 출력 배열의 반환 값입니다.

NumPy의 몇 가지 일반적인 통용 함수
함수사용 방법
sqrt()시리얼라이즈된 데이터의 제곱근 계산
sin(), cos()삼각 함수
abs()시리얼라이즈된 데이터의 절대값 계산
dot()마트릭스 연산
log(), logl(), log2()로그 함수
exp()지수 함수
cumsum(), cumproduct()촉적 합, 촉적 곱
sum()시리얼라이즈된 데이터에 대해 합을 구합니다
mean()평균 계산
median()중앙값 계산
std()표준편차 계산
var()분산 계산
corrcoef()상관계수 계산

math과 numpy 함수의 성능 비교

import time
 import math
 import numpy as np
 x = [i * 0.001 for i in np.arange(1000000)
 start = time.clock()
 for i, t in enumerate(x):
 x[i] = math.sin(t)
 print ("math.sin:", time.clock()) - start )
 x = [i * 0.001 for i in np.arange(1000000)
 x = np.array(x)
 start = time.clock()
 np.sin(x)
 print ("numpy.sin:", time.clock()) - start )

실행 결과:

math.sin: 0.5169950000000005
 numpy.sin: 0.05381199999999886

그래서 NumPy.sin은 math.sin보다 거의 10 배.

벡터화

순회 문을 벡터 기반 작업으로 변환하는 것을 벡터화라고 합니다.
모던 CPU는 이러한 작업을 최적화했기 때문에 더 빠르게 합니다.
두 개의 리스트의 요소를 더합니다:
list 1: [1, 2, 3, 4]
list 2: [4, 5, 6, 7]
하나의 방법은 두 개의 리스트를 순회하며 각 요소를 더하는 것입니다.

ufunc이 없으면, Python의 내장 zip() 메서드를 사용할 수 있습니다.:

x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = []
 for i, j in zip(x, y):
   z.append(i + j)
 print(z)

실행 결과:

[5, 7, 9, 11]

에 대해, NumPy는 add(x, y)라는 ufunc을 가지고 있으며, 이는 동일한 결과를 출력합니다. ufunc을 통해 add() 함수를 사용할 수 있습니다.:

import numpy as np
 x = [1, 2, 3, 4]
 y = [4, 5, 6, 7]
 z = np.add(x, y)
 print(z)

실행 결과:

[5, 7, 9, 11]

루프와 벡터 연산 비교

Python의 NumPy 라이브러리의 내장 함수(Built-in Function)를 최대한 활용하세요-함수 내에서 실행되도록 함으로써 계산의 벡터화를 통해 성능을 크게 향상시킬 수 있습니다. NumPy 라이브러리의 내장 함수는 SIMD 명령어를 사용합니다. 아래에서 사용하는 벡터화는 루프를 사용하는 것보다 훨씬 빠릅니다. GPU를 사용하면 성능이 더 높아질 수 있지만, NumPy는 GPU를 지원하지 않습니다.
아래 코드를 확인하십시오:

import time
 import numpy as np
 x1 = np.random.rand(1000000)
 x2 = np.random.rand(1000000)
 ## for 루프를 사용하여 벡터 내적을 계산하기
 tic = time.process_time()
 dot = 0
 for i in range(len(x1)):
 dot+= x1[i]*x2[i]
 toc = time.process_time()
 print("dot = " + str(dot) + ## for 루프를 사용하여 벡터 내적을 계산하기-----계산 시간 = " + str(1000*(toc - tic)) + "ms")
 ## NumPy 함수를 사용하여 내적을 구하기
 tic = time.process_time()
 dot = 0
 dot = np.dot(x1,x2)
 toc = time.process_time()
 print("dot = " + str(dot) + "\n Verctor 버전---- 계산 시간 = " + str(1000*(toc - tic)) + "ms")

실행 결과:

 dot = 250215.601995
 for 루프-----계산 시간 = 798.3389819999998ms
 dot = 250215.601995
 Verctor 버전---- 계산 시간 = 1.885051999999554ms