11.3 通用函数 (UFuncs) 深入


文档摘要

11.3 通用函数 (UFuncs) 深入 NumPy 通用函数 (UFuncs) 深入 NumPy 的通用函数 (UFuncs) 是对 ndarray 中的数据执行元素级运算的函数。UFuncs 的核心优势在于它们经过高度优化,能够利用向量化操作,从而显著提升 NumPy 代码的性能。本章将深入探讨 UFuncs 的各个方面,包括其原理、类型、使用方法、自定义以及性能优化技巧。 UFuncs 的基本概念 1.1 什么是 UFuncs? UFuncs 是一种函数,它接受一个或多个数组作为输入,并产生一个或多个数组作为输出。关键特性是它们对数组中的每个元素独立地应用操作,而无需显式的循环。 1.

11.3 通用函数 (UFuncs) 深入

NumPy 通用函数 (UFuncs) 深入

NumPy 的通用函数 (UFuncs) 是对 ndarray 中的数据执行元素级运算的函数。UFuncs 的核心优势在于它们经过高度优化,能够利用向量化操作,从而显著提升 NumPy 代码的性能。本章将深入探讨 UFuncs 的各个方面,包括其原理、类型、使用方法、自定义以及性能优化技巧。

1. UFuncs 的基本概念

1.1 什么是 UFuncs?

UFuncs 是一种函数,它接受一个或多个数组作为输入,并产生一个或多个数组作为输出。关键特性是它们对数组中的每个元素独立地应用操作,而无需显式的循环。

1.2 UFuncs 的类型

NumPy 提供了两种类型的 UFuncs:

  • 一元 UFuncs (Unary UFuncs): 接受单个输入数组,例如 np.abs(), np.sqrt(), np.exp()

  • 二元 UFuncs (Binary UFuncs): 接受两个输入数组,例如 np.add(), np.subtract(), np.multiply(), np.divide()

1.3 UFuncs 的特性

  • 向量化: UFuncs 能够以向量化的方式处理整个数组,避免了 Python 循环的开销。

  • 广播 (Broadcasting): UFuncs 自动处理不同形状的数组之间的运算,只要它们的形状满足广播规则。

  • 输出参数 (out): 可以指定输出数组,将结果存储到预先分配的内存中,避免不必要的内存分配。

  • 可选参数: 许多 UFuncs 接受可选参数,例如 where 用于条件运算。

2. 常用 UFuncs

NumPy 提供了大量的内置 UFuncs,涵盖了各种数学、逻辑和位运算。以下是一些常用的 UFuncs:

2.1 数学 UFuncs

  • np.add(x, y): 加法

  • np.subtract(x, y): 减法

  • np.multiply(x, y): 乘法

  • np.divide(x, y): 除法

  • np.floor_divide(x, y): 地板除法(向下取整)

  • np.power(x, y): 幂运算

  • np.mod(x, y): 取模

  • np.abs(x): 绝对值

  • np.sqrt(x): 平方根

  • np.exp(x): 指数

  • np.log(x): 自然对数

  • np.sin(x), np.cos(x), np.tan(x): 三角函数

2.2 比较 UFuncs

  • np.equal(x, y): 等于

  • np.not_equal(x, y): 不等于

  • np.less(x, y): 小于

  • np.less_equal(x, y): 小于等于

  • np.greater(x, y): 大于

  • np.greater_equal(x, y): 大于等于

2.3 逻辑 UFuncs

  • np.logical_and(x, y): 逻辑与

  • np.logical_or(x, y): 逻辑或

  • np.logical_not(x): 逻辑非

  • np.logical_xor(x, y): 逻辑异或

3. UFuncs 的使用方法

3.1 基本用法

UFuncs 可以像普通函数一样调用,也可以使用运算符重载。

import numpy as np x = np.array([1, 2, 3, 4]) y = np.array([5, 6, 7, 8]) # 使用函数调用 result = np.add(x, y) print(result) # 输出: [ 6 8 10 12] # 使用运算符重载 result = x + y print(result) # 输出: [ 6 8 10 12]

3.2 out 参数

out 参数允许我们将 UFunc 的结果存储到预先分配的数组中。这可以避免不必要的内存分配,提高性能。

import numpy as np x = np.array([1, 2, 3, 4]) y = np.array([5, 6, 7, 8]) result = np.empty(x.shape) # 创建一个空数组 np.add(x, y, out=result) print(result) # 输出: [ 6. 8. 10. 12.]

3.3 where 参数

where 参数允许我们根据条件选择性地应用 UFunc。

import numpy as np x = np.array([1, 2, 3, 4]) y = np.array([5, 6, 7, 8]) result = np.where(x < 3, x, y) # 如果 x < 3,则取 x,否则取 y print(result) # 输出: [5 6 3 4]

3.4 聚合 (Aggregate)

UFuncs 提供了 reduce 方法,用于对数组进行聚合操作。例如,np.add.reduce(x) 相当于 np.sum(x)

import numpy as np x = np.array([1, 2, 3, 4]) sum_x = np.add.reduce(x) print(sum_x) # 输出: 10

3.5 累积 (Accumulate)

UFuncs 提供了 accumulate 方法,用于计算数组的累积结果。例如,np.add.accumulate(x) 相当于 np.cumsum(x)

import numpy as np x = np.array([1, 2, 3, 4]) cumulative_sum = np.add.accumulate(x) print(cumulative_sum) # 输出: [ 1 3 6 10]

4. 自定义 UFuncs

虽然 NumPy 提供了大量的内置 UFuncs,但在某些情况下,我们需要自定义 UFuncs 来满足特定的需求。

4.1 使用 np.frompyfunc

np.frompyfunc 允许我们将 Python 函数转换为 UFunc。

import numpy as np def my_func(x, y): return x + y my_ufunc = np.frompyfunc(my_func, 2, 1) # 2 个输入,1 个输出 x = np.array([1, 2, 3, 4]) y = np.array([5, 6, 7, 8]) result = my_ufunc(x, y) print(result) # 输出: [6 8 10 12]

注意: 使用 np.frompyfunc 创建的 UFuncs 性能通常不如内置 UFuncs,因为它仍然需要在 Python 层面进行循环。

4.2 使用 Numba (推荐)

Numba 是一个即时 (JIT) 编译器,可以将 Python 代码编译为机器码,从而显著提高性能。我们可以使用 Numba 来创建高性能的自定义 UFuncs。

import numpy as np from numba import njit @njit def my_func(x, y): return x + y my_ufunc = np.vectorize(my_func) # 使用vectorize装饰器,使其支持numpy数组 x = np.array([1, 2, 3, 4]) y = np.array([5, 6, 7, 8]) result = my_ufunc(x, y) print(result)

使用 Numba 创建的 UFuncs 性能接近于内置 UFuncs。

4.3 绘制流程图

5. UFuncs 的性能优化

5.1 避免不必要的内存分配

尽量使用 out 参数将结果存储到预先分配的数组中,避免不必要的内存分配。

5.2 利用广播

NumPy 的广播机制可以自动处理不同形状的数组之间的运算。合理利用广播可以简化代码,提高性能。

5.3 使用 Numba

对于复杂的自定义 UFuncs,使用 Numba 可以显著提高性能。

5.4 避免 Python 循环

尽量使用 UFuncs 的向量化操作,避免显式的 Python 循环。

5.5 选择合适的数据类型

选择合适的数据类型可以减少内存占用,提高运算速度。例如,如果不需要浮点数,则可以使用整数类型。

6. 总结

NumPy 的 UFuncs 是进行高效数值计算的关键工具。通过理解 UFuncs 的原理、类型、使用方法和性能优化技巧,我们可以编写出更快速、更简洁的 NumPy 代码。 掌握 UFuncs 对于 NumPy 编程至关重要。


发布者: 作者: 转发
评论区 (0)
U