Numpy教程

NumPy ufunc通用函数

NumPy ufunc通用函数的一些操作
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() 对一个序列化数据进行求和
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 有一个 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 loop----- Computation time = " + 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 version---- Computation time = " + str(1000*(toc - tic)) + "ms")
运行结果:
dot = 250215.601995
for loop----- Computation time = 798.3389819999998ms
dot = 250215.601995
verctor version---- Computation time = 1.885051999999554ms
昵称: 邮箱:
Copyright © 2022 立地货 All Rights Reserved.
备案号:京ICP备14037608号-4