NumPy 中的广播(Broadcasting)是一种允许不同形状的数组进行数值运算的机制。广播机制可以简化 NumPy 数组的运算,使其更加高效。广播的核心思想是在适当的时候“广播”较小数组的形状以匹配较大数组的形状,从而使得形状不同的数组之间可以进行数学运算。

1、广播的规则

NumPy 广播是 NumPy 中的一个重要概念,它允许两个形状不同的数组进行运算。两个数组的后缘维度相同,或者在其中一方的维度为1。广播在缺失或者长度为1的维度上补充。

1)后缘维度

如果两个数组的后缘维度相同,则可以直接进行广播,无需进行任何扩展。

A为(3,4,5)的三维数组,B为(4,5)的二维数组。由于A和B的后缘维度都为(4,5),所以可以进行广播。

代码如下,

import numpy as np

a = np.random.rand(3, 4, 5)
print(a.shape)
b = np.random.rand(4, 5)
print(b.shape)

c = a + b

print(c)

A为(2,3)的二维数组,B为(3,)的1为数组,后缘维度都是3,所以可以进行广播。

代码如下,

import numpy as np

a = np.random.rand(2,3)
print(a.shape)
b = np.random.rand(3)
print(b.shape)

c = a + b

print(c)

2)其中一方维度为1

如果两个数组的后缘维度不同,但其中一方维度的长度为 1,则另一方维度会被拉伸为与其相同的长度。

A为(4,5)的二维数组,B为(4,1)的二维数组,两者维度相同, B的数组中一个维度元素个数为1。

代码如下,

import numpy as np

a = np.random.rand(4,5)
print(a.shape)
b = np.random.rand(4,1)
print(b.shape)

c = a + b

print(c)

A为(4,5)的二维数组,B为(1,5)的二维数组,两者维度相同, B的数组中一个维度元素个数为1。

代码如下,

import numpy as np

a = np.random.rand(4,5)
print(a.shape)
b = np.random.rand(1,5)
print(b.shape)

c = a + b

print(c)

A为(4,5)的二维数组,B为(1,1)的二维数组,两者维度相同, B的数组中一个维度元素个数为1。

代码如下,

import numpy as np

a = np.random.rand(4,5)
print(a.shape)
b = np.random.rand(1,1)
print(b.shape)

c = a + b

print(c)

A为(4,5)的二维数组,B为(1,)的二维数组,两者维度相同, B的数组中一个维度元素个数为1。

代码如下,

import numpy as np

a = np.random.rand(4,5)
print(a.shape)
b = np.random.rand(1)
print(b.shape)

c = a + b

print(c)

2、广播的示例

广播机制可以应用于 NumPy 数组的各种运算,包括加法、减法、乘法、除法、比较运算、逻辑运算等。

1)向量与标量的运算

import numpy as np

a = np.array([1, 2, 3])
b = 2

# b 被广播到与 a 相同的形状
print(a * b)  # 输出 [2 4 6]

2)二维数组与一维数组的运算

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([1, 0, 1])

# b 在第一个维度上被广播
print(a + b)  # 输出 [[2 2 4], [5 5 7]]

3、广播的好处

广播机制可以让 NumPy 数组的运算更加灵活和高效,避免了需要对数组进行 reshape 操作的麻烦。理解和正确使用广播可以极大地提高数据处理和分析的效率。

1)内存高效

广播避免了不必要的内存分配,只是在算法层面上扩展较小的数组。

2)性能优化

广播可以减少大量数据的复制,提高计算性能。

3)代码简洁

可以直接对不同形状的数组进行运算,而不需要显式地调整它们的形状。