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

NumPy的通用函数

NumPy 提供了两种基本的对象,即 ndarray 和 ufunc 对象。ufunc 是 universal function的缩写,意思是“通用函数”,它是一种能对数组的每个元素进行操作的函数。
许多 ufunc 函数都是用C语言级别实现的,因此它们的计算速度非常快。
此外,ufun 比 math 模块中的函数更灵活。math 模块的输入一般是标量,但 NumPy 中的函数可以是向量或矩阵,而利用向量或矩阵可以避免使用循环语句,这点在机器学习、深度学习中非常重要。

为什么要使用 ufuncs?

ufunc 用于在 NumPy 中实现矢量化,这比迭代元素要快得多。
它们还提供广播和其他方法,例如减少、累加等,它们对计算非常有帮助。
ufuncs 还接受其他参数,比如:
where 布尔值数组或条件,用于定义应在何处进行操作。
dtype 定义元素的返回类型。
out 返回值应被复制到的输出数组。

NumPy 中的几个常用通用函数
函数使用方法
sqrt()计算序列化数据的平方根
sin()、cos()三角函数
abs()计算序列化数据的绝对值
dot()矩阵运算
log()、logl()、log2()对数函数
exp()指数函数
cumsum()、cumproduct()累计求和、求积
sum()Somma di una sequenza serializzata
mean()Calcolo della media
median()Calcolo della mediana
std()Calcolo della deviazione standard
var()Calcolo della varianza
corrcoef()Calcolo della correlazione

Confronto delle prestazioni tra le funzioni math e 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

Di conseguenza, numpy.sin è circa 10 volte più veloce rispetto a math.sin.

Vettorizzazione

Convertire istruzioni iterative in operazioni basate su vettori si chiama vettorizzazione.
Poiché i moderni CPU sono ottimizzati per questo tipo di operazioni, la velocità è più rapida.
Aggiungere gli elementi delle due liste:
List 1: [1, 2, 3, 4]
List 2: [4, 5, 6, 7]
Un metodo è esplorare due liste e sommare ogni elemento.

Se non ci sono ufunc, possiamo utilizzare il metodo built-in zip() di Python:

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]

Per questo, NumPy ha un ufunc chiamato add(x, y), che produce lo stesso risultato. Attraverso l'ufunc, possiamo utilizzare la funzione 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]

Confronto tra ciclo e operazioni vettoriali

L'uso dei funzioni built-in della libreria NumPy di Python, per implementare calcoli vettoriali, può migliorare significativamente la velocità di esecuzione. Le funzioni built-in della libreria NumPy utilizzano istruzioni SIMD. L'uso della vettorizzazione, come mostrato di seguito, è molto più veloce rispetto al calcolo con cicli. Se si utilizza una GPU, le prestazioni saranno ancora più potenti, ma NumPy non supporta la GPU.
请看下面的代码:

import time
 import numpy as np
 x1 = np.random.rand(1000000)
 x2 = np.random.rand(1000000)
 ##使用循环计算向量点积
 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) + "\nfor循环-----计算时间 = " + 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) + "\nVerctor 版本---- 计算时间 = " + str(1000*(toc - tic)) + "ms")

运行结果:

 dot = 250215.601995
 for循环-----计算时间 = 798.3389819999998ms
 dot = 250215.601995
 Verctor 版本---- 计算时间 = 1.885051999999554ms