如何使用 Python 和动态数组执行 NumPy 广播?


“广播”指的是 NumPy 在算术运算期间如何处理不同维度的数组。较小的数组会在遵守一定限制的情况下“广播”到较大的数组中,以确保它们的形状一致。广播允许您将数组运算矢量化,使您能够在 C 而不是 Python 中循环。

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

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

在给定数组上执行广播的步骤:

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

  • 步骤 2. 打印给定数组

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

  • 步骤 4. 打印结果数组

添加两个不同维度的数组

使用 arange() 函数创建一个包含从 0 到 n-1 的数字的 NumPy 数组(arange() 函数返回在给定区间内均匀分布的值。在半开区间 [start, stop] 内生成值),并向其中添加一个常数。

示例

import numpy as np # Getting list of numbers from 0 to 7 givenArray = np.arange(8) # Adding a number to the numpy array result_array = givenArray + 9 print("The input array",givenArray) print("Result array after adding 9 to the input array",result_array)

输出

The input array [0 1 2 3 4 5 6 7]
Result array after adding 9 to the input array [ 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 # Getting the list of numbers from 0 to 11 and reshaping it to 3 rows and 4 columns givenArray_1 = np.arange(12).reshape(3, 4) # Printing the shape(rowsize, columnsize) of array print("The shape of Array_1 = ", givenArray_1.shape) # Getting list of numbers from 0 to 2 and reshaping it to 3 rows and 1 columns givenArray_2 = np.arange(3).reshape(3, 1) print("The shape of Array_2 = ", givenArray_2.shape) # Summing both the arrays print("Input array 1 \n",givenArray_1) print("Input array 2 \n",givenArray_2) print("Summing both the arrays:") print(givenArray_1 + givenArray_2)

输出

The shape of Array_1 =  (3, 4)
The shape of Array_2 =  (3, 1)
Input array 1 
 [[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11] ]
Input array 2 
 [[0]
  [1]
  [2]]
Summing both the arrays:
[[ 0  1  2  3]
 [ 5  6  7  8]
 [10 11 12 13]]

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

将两个维度不兼容的数组求和

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

示例

import numpy as np # Getting a list of numbers from 0 to 11 and reshaping it to 3 rows and 4 columns givenArray_1 = np.arange(20).reshape(6, 4) # Printing the shape(rowsize, columnsize) of array print("The shape of Array_1 = ", givenArray_1.shape) # Getting list of numbers from 0 to 5 and reshaping it to 3 rows and 1 columns givenArray_2 = np.arange(6).reshape(6, 1) print("The shape of Array_2 = ", givenArray_2.shape) # Summing both the arrays print("Summing both the arrays:") 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 # Getting list of numbers from 0 to 14 and reshaping it to 5 rows and 3 columns givenArray_1 = np.arange(15).reshape(5, 3) # Printing the shape(rowsize, columnsize) of array print("The shape of Array_1 = ", givenArray_1.shape) # Getting list of numbers from 0 to 2 givenArray_2 = np.arange(3) print("The shape of Array_2 = ", givenArray_2.shape) # Summing both the arrays print("Array 1 \n",givenArray_1) print("Array 2 \n",givenArray_2) print("Summing both the arrays: \n",givenArray_1 + givenArray_2)

输出

The shape of Array_1 =  (5, 3)
The shape of Array_2 =  (3,)
Array 1 
 [[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]
  [12 13 14]]
Array 2 
 [0 1 2]
Summing both the arrays: 
 [[ 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("The shape of Array_1: ", givenArray_1.shape) givenArray_2 = np.arange(20).reshape(5, 4, 1) print("The shape of Array_2: ", givenArray_2.shape) # Summing both the arrays and printing the shape of it print("Summing both the arrays and printing the shape of it:") print((givenArray_1 + givenArray_2).shape)

输出

The shape of Array_1:  (6, 5, 4, 2)
The shape of Array_2:  (5, 4, 1)
Summing both the arrays and printing the shape of it:
(6, 5, 4, 2)

务必理解,多个数组可以沿多个维度进行传播。Array1 的维度为 (6, 5, 4, 2),而 array2 的维度为 (5, 4, 1)。维度数组是通过沿第三维拉伸 array1 和沿第一和第二维拉伸 array2 形成的 (6, 5, 4, 2)。

结论

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

更新于:2022年8月17日

248 次浏览

启动您的 职业生涯

通过完成课程获得认证

开始
广告