使用 NumPy 广播实现高效计算

NumPyNumPyBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

广播(Broadcasting)是NumPy中一项强大的功能,它允许形状不同的数组用于算术运算。它提供了一种向量化数组操作的方法,并提高了计算效率。本实验将指导你了解NumPy中广播的基础知识。

注意:你可以在05-broadcasting.ipynb中编写代码。步骤中省略了一些打印操作,你可以根据需要打印输出。

理解广播

广播功能使NumPy能够对形状不同的数组执行逐元素操作。较小的数组会自动“广播”以匹配较大数组的形状。这是在特定约束条件下完成的,我们将在后续步骤中进行探讨。

对形状相同的数组进行广播

在最简单的情况下,两个数组必须具有完全相同的形状才能进行逐元素操作。例如:

import numpy as np

a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
result = a * b

在这种情况下,ab 具有相同的形状,因此乘法是逐元素进行的,结果是 [2.0, 4.0, 6.0]

对标量值进行广播

广播还允许在数组和标量值之间进行逐元素操作。标量值会自动“扩展”以匹配数组的形状。例如:

import numpy as np

a = np.array([1.0, 2.0, 3.0])
b = 2.0
result = a * b

在这种情况下,b 是一个标量值,但它会被扩展为与 a 形状相同的数组。然后进行逐元素乘法,结果为 [2.0, 4.0, 6.0]

通用广播规则

NumPy 会逐元素比较两个数组的形状,以确定它们是否兼容广播。适用以下规则:

  1. 如果两个维度的大小相等,则它们兼容。
  2. 如果其中一个维度的大小为 1,则它们兼容。

如果不满足这些条件,将引发 ValueError,表明数组形状不兼容。

广播示例

让我们来看一些示例,以了解广播在不同场景下是如何工作的。

  • 示例1:
import numpy as np

a = np.array([[1.0, 2.0, 3.0],
              [4.0, 5.0, 6.0]])
b = np.array([1.0, 2.0, 3.0])
result = a + b

在这种情况下,b 被加到 a 的每一行上。结果是一个与 a 形状相同的二维数组,其中每个元素是 ab 中对应元素的和。

  • 示例2:
import numpy as np

a = np.array([[1.0, 2.0, 3.0],
              [4.0, 5.0, 6.0]])
b = np.array([1.0, 2.0])
result = a + b

在这种情况下,广播失败,因为 ab 的尾部维度不相等。无法将 a 各行中的值与 b 的元素进行对齐以进行逐元素加法。

实际示例 - 矢量量化

让我们探讨一个广播很有用的实际示例。考虑信息论和分类中使用的矢量量化(VQ)算法。VQ 中的基本操作是在一组点中找到与给定点最接近的点。这可以通过广播来完成。以下是一个示例:

import numpy as np

observation = np.array([111.0, 188.0])
codes = np.array([[102.0, 203.0],
                  [132.0, 193.0],
                  [45.0, 155.0],
                  [57.0, 173.0]])
diff = codes - observation
dist = np.sqrt(np.sum(diff**2, axis=-1))
closest_index = np.argmin(dist)
closest_code = codes[closest_index]

在这个示例中,observation 表示要分类的运动员的体重和身高,codes 表示不同类别的运动员。通过从 codes 中减去 observation,使用广播来计算 observation 与每个代码之间的距离。然后使用 argmin 函数找到最接近代码的索引。

总结

在本实验中,我们学习了 NumPy 中的广播。广播允许对形状不同的数组进行逐元素操作,使其成为向量化数组操作和提高计算效率的强大工具。通过理解广播规则并适当地使用它,你可以简化和优化你的代码。