NumPy - ufunc 简介
NumPy 通用函数 (ufunc)
Ufunc,即通用函数,是 NumPy 中对 ndarray 逐元素执行操作的函数。它们充当简单函数的向量化包装器,这意味着它们可以同时对数组中的每个元素执行相同的操作,这比使用传统的 Python 循环要快得多。
UFunc 的常见示例包括加、减、乘、除等基本算术运算,以及三角函数、对数函数和指数函数等更复杂的函数。
创建和使用 ufunc
NumPy 提供了各种内置 ufunc 来执行常见操作。您还可以使用 numpy.frompyfunc() 函数创建自定义 ufunc,该函数允许您将 Python 函数转换为 ufunc。让我们探索如何使用内置和自定义 ufunc。
示例:使用内置 ufunc
在本例中,我们使用内置 ufunc numpy.add() 对两个数组执行元素级加法 -
import numpy as np # 定义两个数组 a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 使用内置 ufunc numpy.add 将两个数组相加 result = np.add(a, b) print(result)
以下是得到的结果 -
[5 7 9]
示例:创建自定义 ufunc
在此示例中,我们使用 numpy.frompyfunc() 函数创建一个自定义 ufunc。此 ufunc 将对两个数组执行元素乘法 -
import numpy as np # 定义一个用于乘法的 Python 函数 def multiply(x, y): return x * y # 从 Python 函数创建一个自定义 ufunc multiply_ufunc = np.frompyfunc(multiply, 2, 1) # 定义两个数组 a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 使用自定义 ufunc 进行数组乘法 result = multiply_ufunc(a, b) print(result)
这将产生以下结果 -
[4 10 18]
使用 ufunc 的优势
与传统的基于循环的方法相比,在 NumPy 中使用 ufunc 具有以下几个优势:-
- 性能:ufunc 经过高度优化,执行操作的速度比等效的 Python 循环快得多。
- 矢量化:ufunc 一次操作整个数组,无需显式循环并降低出错的可能性。
- 广播:ufunc 支持广播,允许您以灵活的方式对不同形状的数组执行操作。
- 灵活性:ufunc 可以处理各种操作,从简单的算术到复杂的数学函数。
使用ufuncs
广播是 NumPy 的一项功能,允许 ufuncs 对不同形状的数组进行操作。当对不同大小的数组执行操作时,NumPy 会自动将较小的数组广播到较大的数组,以使它们具有兼容的形状。
例如,您可以向数组添加一个标量,或者添加两个不同形状的数组,NumPy 会为您处理广播。
示例
在此示例中,我们使用 NumPy 中的广播功能向数组添加一个标量 -
import numpy as np # 定义一个数组 a = np.array([1, 2, 3]) # 使用广播向数组添加一个标量 result = np.add(a, 5) print(result)
以下是上述代码的输出 -
[6 7 8]
NumPy 中常用的 ufunc
NumPy 提供了一套完整的内置 ufunc 来执行各种操作。一些最常用的 ufunc 有:-
- 算术 ufunc: np.add()、np.subtract()、np.multiply()、np.divide()
- 三角函数 ufunc: np.sin()、np.cos()、np.tan()、np.arcsin()、np.arccos()、np.arctan()
- 指数和对数 ufunc: np.exp()、np.log()、np.log10()、np.log2()
- 比较 ufunc: np.greater()、np.less()、np.equal() np.not_equal()
示例:使用三角函数 ufuncs
在本例中,我们使用三角函数 ufuncs numpy.sin() 计算数组中每个元素的正弦值 -
import numpy as np # 定义一个以弧度为单位的角度数组 angles = np.array([0, np.pi/2, np.pi]) # 使用三角函数 ufuncs numpy.sin 计算每个角度的正弦值 sine_values = np.sin(angles) print(sine_values)
得到的输出如下所示 -
[0.0000000e+00 1.0000000e+00 1.2246468e-16]
示例:使用指数 ufunc
这里,我们使用指数 ufunc numpy.exp() 计算数组中所有元素的指数 -
import numpy as np # 数组 arr = np.array([1, 2, 3]) # 计算每个元素的指数 exp_result = np.exp(arr) print("每个元素的指数:", exp_result)
执行上述代码后,我们得到以下输出 -
每个元素的指数:[ 2.71828183 7.3890561 20.08553692]
示例:使用对数通用函数
现在,我们使用对数通用函数 numpy.log() 计算数组中所有元素的自然对数(底数为 e)-
import numpy as np # 数组 arr = np.array([1, np.e, np.e**2]) # 计算每个元素的自然对数 log_result = np.log(arr) print("每个元素的自然对数:", log_result)
我们得到如下所示的输出 −
每个元素的自然对数:[0. 1. 2.]
示例:使用比较通用函数
这里我们使用比较通用函数 numpy.greater(),它逐个元素比较两个数组,并返回一个布尔值数组,指示第一个数组的元素大于第二个数组的元素 -
import numpy as np # 数组 arr1 = np.array([1, 2, 3]) arr2 = np.array([2, 2, 2]) # 将 arr1 中的每个元素与 arr2 进行比较 comparison_result = np.greater(arr1, arr2) print("比较结果 (arr1 > arr2):", comparison_result)
生成的结果如下 -
比较结果 (arr1 > arr2): [False False True]