numpy 广播详解(Broadcasting)
NumPy 的 广播(Broadcasting) 是一种强大的机制,允许在不同形状的数组之间执行元素级运算(如加减乘除),而无需显式复制数据。它通过智能地扩展较小数组的维度来实现高效计算,是向量化操作的核心。
前言shape详解
在NumPy中,数组的形状(shape)是一个描述数组每个维度大小的元组。形状(2, 3, 4)表示一个三维数组,其中:
第一个维度(也称为轴0)的大小为2
第二个维度(轴1)的大小为3
第三个维度(轴2)的大小为4
我们可以这样理解:
这个数组有2个“层”(第一维)
每个“层”有3行(第二维)
每行有4个元素(第三维)
例如,一个形状为(2,3,4)的数组可以看作是两个3行4列的矩阵(即两个3x4的矩阵)。
我们可以用以下代码创建一个形状为(2,3,4)的数组并查看其内容:
import numpy as np
#创建一个形状为(2,3,4)的数组,元素从0到23
arr = np.arange(24).reshape(2, 3, 4)
print(arr)
输出将类似于:[[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]][[12 13 14 15][16 17 18 19][20 21 22 23]]]
在这个数组中:
第一层(索引0)是一个3x4的矩阵:
[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9, 10, 11]
第二层(索引1)是另一个3x4的矩阵:
[12, 13, 14, 15]
[16, 17, 18, 19]
[20, 21, 22, 23]
当我们访问数组时:
arr[0]会返回一个形状为(3,4)的数组(第一层)
arr[0, 1]会返回第一层第二行的数组:[4,5,6,7]
arr[0, 1, 2]会返回第一层第二行第三列的元素:6
总结:形状(2,3,4)表示一个三维数组,由2个3x4的矩阵组成。
一、广播的核心规则
广播遵循两条严格规则,按顺序检查:
1、维度对齐(尾部对齐)
将两个数组的维度从尾部(最右边)开始对齐。若维度不等,在较小数组的左侧补 1,直到维度相同。示例:
- A.shape = (3, 4),B.shape = (4,)
→ 对齐后:A.shape = (3, 4),B.shape = (1, 4) - A.shape = (8, 3, 2),B.shape = (2,)
→ 对齐后:A.shape = (8, 3, 2),B.shape = (1, 1, 2) - A.shape = (9, 4, 3),B.shape = (2,)
→ 对齐后:A.shape =(9, 4, 3),B.shape = (1, 1, 2)
2、尺寸兼容性检查
对齐后的每个维度尺寸需满足以下条件之一:
- 相等
- 其中一个为 1(此时会沿该维度复制数据)
- 不满足则抛出 ValueError。
示例:
A.shape = (3, 4),B.shape = (1, 4)→ 兼容(B 沿第0维复制3次)
A.shape = (3, 4),B.shape = (2, 4)→ 不兼容(第0维 3≠2 且均不为1)
A.shape = (3, 1, 5),B.shape = (4, 5)→ 兼容(B 扩展为 (1,4,5),A 沿第1维复制4次,B沿着第0维复制三次,最终A与B的形状相同,且数据是从元数据按照某一维度复制来的)
二、广播的典型场景
1、数组与标量运算
import numpy as np
arr = np.array([[1, 2], [3, 4]])
result = arr * 10 # 标量10被广播为 [[10,10], [10,10]]
广播过程:
arr.shape = (2, 2),10.shape = ()
标量补维 → 10.shape = (1, 1)
沿两个维度复制 → (2, 2)
2、行向量与列向量相加
a = np.array([1, 2, 3]) # shape=(3,) → (1,3)
b = np.array([[10], [20]]) # shape=(2,1),相当于一列数据 10,20
result = a + b # 输出:[[11,12,13], [21,22,23]]
广播过程:
a.shape = (3,)→ 补维 (1,3)
b.shape = (2,1)
扩展:
a沿第0维复制 → shape=(2,3)
b沿第1维复制 → shape=(2,3)
3、高维数组广播
A = np.arange(24).reshape(2, 3, 4) # shape=(2,3,4)
B = np.array([100, 200, 300, 400]) # shape=(4,) → (1,1,4)
C = A + B # B被广播到(2,3,4)
广播过程:
B.shape = (4,)→ 补维 (1,1,4)
沿第0维复制2次、第1维复制3次 → 与A同形
