NumPy实现广播机制与广播规则的示例

 更新时间:2026年05月07日 10:03:17   作者:MediaTea  
NumPy中的广播机制,这是一种允许不同形状数组之间进行逐元素运算的技术,本文就来详细的介绍一下NumPy实现广播机制与广播规则的示例,感兴趣的可以了解一下

在 NumPy 中,广播(Broadcasting)是一组形状匹配规则,用于支持逐元素运算在不同形状数组之间自动对齐,从而在不编写 Python 循环、不显式复制数据的前提下,实现高效的向量化计算。

一、什么是广播?

我们知道,当两个数组形状相同,二元运算会逐元素执行:

import numpy as np
a = np.array([0, 1, 2])b = np.array([5, 5, 5])
a + b

输出:array([5, 6, 7])

广播允许对不同形状的数组执行类似的逐元素运算。

例如,可以将一个标量(可以将其视为一个 0 维数组)加到数组上:

a + 5

输出:array([5, 6, 7])

可以将其理解为将数值 5 “拉伸”或“复制”为 [5, 5, 5] 后再进行相加。

但需要强调的是,NumPy 并不会创建 [5, 5, 5] 再相加,而是在计算过程中将标量“广播”到数组的每个元素。

这种机制不仅适用于标量,也适用于更高维的数组,只要满足一定规则。

观察一维数组与二维数组相加的结果:

M = np.ones((3, 3))M

输出:array([[1., 1., 1.],       [1., 1., 1.],       [1., 1., 1.]])

再执行:

M + a

输出:array([[1., 2., 3.],       [1., 2., 3.],       [1., 2., 3.]])

此处,一维数组 a 被“拉伸”或广播到第二个维度,以匹配 M 的形状。

这些示例较为直观。但在更复杂的情况下,两个数组都可能发生广播。请看下例:

a = np.arange(3)b = np.arange(3)[:, np.newaxis]
print(a)print(b)

输出:[0 1 2][[0] [1] [2]]

当执行:a + b

输出:array([[0, 1, 2],       [1, 2, 3],       [2, 3, 4]])

正如前述例子中将一个值“拉伸”以匹配另一个数组的形状一样,在这里,a 和 b 都被“拉伸”到一个共同形状,结果是一个二维数组。

下图展示了这些示例的几何结构。

浅色区域表示被广播的值。再次强调,这些额外内存在实际计算中并未真正分配,但在概念上进行这样的想象有助于理解什么是“广播”。

要注意的是,广播只发生在:

  • 逐元素 ufunc
  • 运算符重载运算

不会发生在:

  • 矩阵乘法 @ 和 matmul
  • 点积 dot

二、广播规则

NumPy 中的广播遵循一套严格规则和步骤来确定两个数组之间如何交互。

广播比较是从最后一维(尾维)开始对齐,正确广播后的结果形状等于“各维度取最大值”。

  • 规则 1:如果两个数组的维度数不同,则在维度较少的数组形状左侧补 1。
  • 规则 2: 若在某一维上(从最后一维开始)两个数组的形状不相同,则该维度中长度等于 1 的数组会被扩展至与另一数组匹配。
  • 规则 3: 如果在任意维度上两个数组的大小不同,且长度都不等于 1,则抛出错误。

下面通过具体示例说明。

广播示例 1:将二维数组与一维数组相加

M = np.ones((2, 3))a = np.arange(3)

数组形状为:

M.shape = (2, 3)a.shape = (3,)

根据规则 1,对 a 的形状左侧补 1:

M.shape -> (2, 3)a.shape -> (1, 3)

根据规则 2,第一维不一致,因此将其扩展:

M.shape -> (2, 3)a.shape -> (2, 3)

形状匹配,结果形状为 (2, 3):

M + a

输出:array([[1., 2., 3.],       [1., 2., 3.]])

广播示例 2:两个数组都需要广播

a = np.arange(3).reshape((3, 1))b = np.arange(3)

形状:

a.shape = (3, 1)b.shape = (3,)

首先按照规则 1,数组 b 的形状左侧补 1:

a.shape -> (3, 1)b.shape -> (1, 3)

然后按照规则 2,先后扩展数组 a 的形状和数组 b 的形状:

a.shape -> (3, 3)b.shape -> (3, 3)

由于最终形状一致,因此这两个数组的形状是兼容的。下面可以看到这一点:

a + b

输出:array([[0, 1, 2],       [1, 2, 3],       [2, 3, 4]])

广播示例 3:不兼容的情形

M = np.ones((3, 2))a = np.arange(3)

形状:

M.shape = (3, 2)a.shape = (3,)

首先按照规则 1,数组 a 的形状左侧补 1:

M.shape -> (3, 2)a.shape -> (1, 3)

然后按照规则 2,第二维比较时发现 2 ≠ 3 且均不为 1,此时触发规则 3,最终形状不一致,因此不兼容。

当执行:

M + a

会产生:ValueError: operands could not be broadcast together with shapes (3,2) (3,)

需要注意的是,不能假设右侧补 1。广播规则只允许在左侧补 1。若需要右侧补 1,必须显式 reshape:

a.reshape(3, 1)# (3, 1)

或者:

a[:, np.newaxis]# 等价于a[:, None]

当执行:

M + a[:, np.newaxis]

输出:array([[1., 1.],       [2., 2.],       [3., 3.]])

广播规则适用于所有二元通用函数(ufunc)。例如:

np.logaddexp(M, a[:, np.newaxis])
array([[1.31326169, 1.31326169],       [1.69314718, 1.69314718],       [2.31326169, 2.31326169]])

logaddexp(x, y) 计算 log(exp(x) + exp(y)),并以更高数值精度实现。

三、NumPy 广播的实际应用

1、数据中心化

假设有 10 条观测数据,每条包含 3 个特征,存储为 10×3 数组:

X = np.random.random((10, 3))

计算每个特征的均值:

Xmean = X.mean(0)# array([0.56171119, 0.37035172, 0.56328698])

中心化数据:

X_centered = X - Xmean

验证均值是否接近 0:

X_centered.mean(0)# array([ 5.55111512e-17, -4.44089210e-17, -7.77156117e-17])

结果在机器精度范围内接近 0。

2、绘制二维函数

广播在生成二维函数图像时非常有用。

x = np.linspace(0, 5, 50)y = np.linspace(0, 5, 50)[:, np.newaxis]
z = np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)

x 与 y 自动广播生成 50×50 网格。

使用 Matplotlib 可视化:

import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', extent=[0, 5, 0, 5],           cmap='viridis')plt.colorbar()

广播使二维函数的计算无需显式双重循环。

小结

广播是一组严格规则,用于支持不同形状数组之间的逐元素运算:

  • 维度不足时在左侧补 1
  • 从右向左逐维比较,每一维必须“相等或存在 1”
  • 不满足条件则报错

广播机制是 NumPy 向量化计算的重要基础,广泛应用于科学计算、机器学习与数据分析中。

到此这篇关于NumPy实现广播机制与广播规则的示例的文章就介绍到这了,更多相关NumPy 广播机制与广播规则内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python+Matplotlib+LaTeX玩转数学公式

    Python+Matplotlib+LaTeX玩转数学公式

    这篇文章主要为大家介绍了如何在Matplotlib中使用LaTeX 公式和符号以及Python如何生成LaTeX数学公式。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-02-02
  • python+opencv实现动态物体追踪

    python+opencv实现动态物体追踪

    这篇文章主要为大家详细介绍了python+opencv实现动态物体的追踪,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 使用python获取cpu每秒的使用率

    使用python获取cpu每秒的使用率

    这篇文章主要介绍了使用python获取cpu每秒的使用率,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • python文件转为exe文件的方法及用法详解

    python文件转为exe文件的方法及用法详解

    py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样,你就可以不用装python而在windows系统上运行这个可执行程序。本文重点给大家介绍python文件转为exe文件的方法,感兴趣的朋友跟随小编一起看看吧
    2019-07-07
  • 基于Python实现成语填空游戏的示例代码

    基于Python实现成语填空游戏的示例代码

    成语填空想必大家都是十分熟悉的了,特别是有在上小学的家长肯定都有十分深刻的印象。当然了你也别小看了成语调控小游戏,有的时候知识储备不够,你还真的不一定猜得出来是什么。本文就来用Python编写一个简单的成语填空游戏,感兴趣的可以了解下
    2023-02-02
  • Python鼠标事件及坐标获取窗口和屏幕坐标

    Python鼠标事件及坐标获取窗口和屏幕坐标

    这篇文章主要介绍了Python编程中如何通过鼠标事件及坐标获取窗口坐标和屏幕坐标的示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • 自定义Django Form中choicefield下拉菜单选取数据库内容实例

    自定义Django Form中choicefield下拉菜单选取数据库内容实例

    这篇文章主要介绍了自定义Django Form中choicefield下拉菜单选取数据库内容实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • 如何用Python画一些简单形状你知道吗

    如何用Python画一些简单形状你知道吗

    这篇文章主要介绍了用Python作图的一个简单实例,通过turtle模块实现作图,具有一定参考价值,需要的朋友可以了解下希望能给你带来帮助
    2021-08-08
  • python如何在循环引用中管理内存

    python如何在循环引用中管理内存

    这篇文章主要为大家详细介绍了python如何在循环引用中管理内存,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Matplotlib之解决plt.savefig()保存多张图片有重叠的问题

    Matplotlib之解决plt.savefig()保存多张图片有重叠的问题

    这篇文章主要介绍了Matplotlib之解决plt.savefig()保存多张图片有重叠的问题,具有很好的参考价值,希望对大家有所帮助,
    2023-09-09

最新评论