NumPy 提供了两种基本的对象,即 ndarray 和 ufunc 对象。ufunc 是 universal function的缩写,意思是“通用函数”,它是一种能对数组的每个元素进行操作的函数。 
许多 ufunc 函数都是用C语言级别实现的,因此它们的计算速度非常快。 
此外,ufun 比 math 模块中的函数更灵活。math 模块的输入一般是标量,但 NumPy 中的函数可以是向量或矩阵,而利用向量或矩阵可以避免使用循环语句,这点在机器学习、深度学习中非常重要。
ufunc 用于在 NumPy 中实现矢量化,这比迭代元素要快得多。 
 它们还提供广播和其他方法,例如减少、累加等,它们对计算非常有帮助。 
 ufuncs 还接受其他参数,比如: 
 where 布尔值数组或条件,用于定义应在何处进行操作。 
 dtype 定义元素的返回类型。 
 out 返回值应被复制到的输出数组。
| 函数 | 使用方法 | 
| sqrt() | 计算序列化数据的平方根 | 
| sin()、cos() | 三角函数 | 
| abs() | 计算序列化数据的绝对值 | 
| dot() | 矩阵运算 | 
| log()、logl()、log2() | 对数函数 | 
| exp() | 指数函数 | 
| cumsum()、cumproduct() | 累计求和、求积 | 
| sum() | 对一个序列化数据进行求和 | 
| mean() | 计算均值 | 
| median() | 计算中位数 | 
| std() | 计算标准差 | 
| var() | 计算方差 | 
| corrcoef() | 计算相关系数 | 
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 有一个 ufunc,名为 add(x, y),它会输出相同的结果,通过 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)
 ##使用循环计算向量点积
 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) + "\n 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