如何使用 Python 的动态数组执行 Numpy 广播?

programmingpythonserver side programming更新于 2025/3/19 12:28:17

"广播"是指 NumPy 在算术运算期间如何处理不同维度的数组。较小的数组在较大的数组上"广播",但要受到某些限制,以确保它们的形状一致。广播允许您对数组操作进行矢量化,从而允许您在 C 而不是 Python 中循环。

这无需不必要的数据复制即可实现,从而实现高效的算法实现。在某些情况下,广播是一个消极的想法,因为它会导致内存浪费,从而减慢计算速度。

在本文中,我们将向您展示如何使用python对NumPy数组执行广播。

对给定数组执行广播的步骤-

  • 步骤1.创建两个兼容维度的数组

  • 步骤2.打印给定的数组

  • 步骤3.使用两个数组执行算术运算

  • 步骤4.打印结果数组

添加两个不同维度的数组

使用arange()函数创建一个由0到n-1的数字组成的numpy数组(arange()函数返回在给定间隔内均匀分布的值。在半开间隔 [开始,停止],生成值)并向其中添加一些常量。

示例

import numpy as np # 获取从 0 到 7 的数字列表 givenArray = np.arange(8) # 将数字添加到 numpy 数组 result_array = givenArray + 9 print("输入数组",givenArray) print("将 9 添加到输入数组后的结果数组",result_array)

输出

输入数组 [0 1 2 3 4 5 6 7]
将 9 添加到输入数组后的结果数组 [ 9 10 11 12 13 14 15 16]

给定的数组有一个维度(轴),长度为8,而 9 是一个没有维度的简单整数。由于它们的维度不同,Numpy 会尝试沿某个轴广播(只是拉伸)较小的数组,使其可以接受数学运算。

对具有兼容维度的两个数组求和

使用 arange() 函数创建两个从 0 到 n-1 的 NumPy 数组,并使用 reshape() 函数对其进行重塑(重塑数组而不影响其数据)。这两个数组具有兼容的维度 (3,4) 和 (3,1),并添加两个数组的相应元素。

示例

import numpy as np # 获取从 0 到 11 的数字列表并将其重新整形为 3 行 4 列 givenArray_1 = np.arange(12).reshape(3, 4) # 打印数组的形状(行大小、列大小) print("Array_1 的形状 = ", givenArray_1.shape) # 获取从 0 到 2 的数字列表并将其重新整形为 3 行 1 列 givenArray_2 = np.arange(3).reshape(3, 1) print("Array_2 的形状 = ", givenArray_2.shape) # 对两个数组求和 print("输入数组 1 \n",givenArray_1) print("输入数组 2 \n",givenArray_2) print("对两个数组求和:") print(givenArray_1 + givenArray_2)

输出

Array_1 的形状 = (3, 4)
Array_2 的形状 = (3, 1)
输入数组 1
 [[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11] ]
输入数组 2
 [[0]
  [1]
  [2]]
对两个数组求和:
[[ 0  1  2  3]
 [ 5  6  7  8]
 [10 11 12 13]]

givenArray_2 沿第二维扩展以匹配 givenArray_1 的维度。由于两个数组的维度兼容,因此可以实现这一点。

对具有不兼容维度的两个数组求和

创建两个具有不兼容维度 (6, 4) 和 (6, 1) 的 NumPy 数组。当我们尝试添加两个数组的相应元素时,它会引发错误,如下所示。

示例

import numpy as np # 获取从 0 到 11 的数字列表并将其重塑为 3 行 4 列 givenArray_1 = np.arange(20).reshape(6, 4) # 打印数组的形状(行大小、列大小) print("Array_1 的形状 = ", givenArray_1.shape) # 获取从 0 到 5 的数字列表并将其重新整形为 3 行 1 列 givenArray_2 = np.arange(6).reshape(6, 1) print("Array_2 的形状 = ", givenArray_2.shape) # 对两个数组求和 print("对两个数组求和:") print(givenArray_1 + givenArray_2)

输出

Traceback (most recent call last):
  File "main.py", line 3, in 
    givenArray_1 = np.arange(20).reshape(6, 4)
ValueError: cannot reshape array of size 20 into shape (6,4)

行数为 6,列数为 4。

它不能插入大小为 20 的矩阵中(它需要大小为 6*4 = 24 的矩阵)。

对 Numpy 多维数组和线性数组求和

使用 arange() 函数创建一个多维数组,并使用 reshape() 函数将其重塑为一些随机数量的行和列。使用 arange() 函数创建另一个线性数组,并对这两个数组求和。

示例 1

import numpy as np # 获取从 0 到 14 的数字列表,并将其重新整形为 5 行 3 列 givenArray_1 = np.arange(15).reshape(5, 3) # 打印数组的形状(行大小、列大小) print("Array_1 的形状 = ", givenArray_1.shape) # 获取列表从 0 到 2 的数字 givenArray_2 = np.arange(3) print("Array_2 的形状 = ", givenArray_2.shape) # 对两个数组求和 print("数组 1 \n",givenArray_1) print("数组 2 \n",givenArray_2) print("对两个数组求和:\n",givenArray_1 + givenArray_2)

输出

Array_1 的形状 = (5, 3)
Array_2 的形状 = (3,)
数组 1
 [[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]
  [12 13 14]]
数组 2 
 [0 1 2]
对两个数组求和: 
 [[ 0  2  4]
  [ 3  5  7]
  [ 6  8 10]
  [ 9 11 13]
  [12 14 16]]
 

给定的线性数组被扩展以匹配给定数组 1(多维数组)的维度。由于两个数组的维度兼容,因此可以实现这一点。

示例 2

import numpy as np givenArray_1 = np.arange(240).reshape(6, 5, 4, 2) print("Array_1 的形状: ", givenArray_1.shape) givenArray_2 = np.arange(20).reshape(5, 4, 1) print("Array_2 的形状: ", givenArray_2.shape) # 对两个数组求和并打印其形状 print("对两个数组求和并打印其形状:") print((givenArray_1 + givenArray_2).shape)

输出

Array_1 的形状:(6, 5, 4, 2)
Array_2 的形状:(5, 4, 1)
对两个数组求和并打印其形状:
(6, 5, 4, 2)

理解多个数组可以沿多个维度传播至关重要。 Array1 的维度为 (6, 5, 4, 2),而 array2 的维度为 (5, 4, 1)。维度数组由沿第三维拉伸 array1 和沿第一维和第二维拉伸 array2 形成 (6, 5, 4, 2)。

结论

Numpy 广播比遍历数组更快。从第一个示例开始。用户可以循环遍历数组,将相同的数字添加到数组中的每个元素,而不是使用广播方法。这很慢,原因有两个:循环需要与 Python 循环交互,这会降低 C 实现的速度。其次,NumPy 使用步幅而不是循环。将步幅设置为 0 允许您无限循环遍历组件,而不会产生内存开销。


相关文章


有用资源