数组的基本运算:大小相等的数组之间的任何算术运算都会将运算应用到元素级
- 对应位置元素直接运算(+ - * /)
广播机制:
- 广播兼容规则:两个维度相等,或者其中一个是 1,就能广播。
- 第一步:自动补齐维度(左边补 1)
- 第二步:广播自动扩展成一样大
- 第三步:逐元素相加
importnumpyasnp# 2.8 基本运算defbaseOperationFun():# numpy中的数组不用编写循环即可执行批量运算,称之为矢量化运算。# 叠加运算即可,大小相等的数组之间的任何算术运算都会将运算应用到元素级。arr1=np.array([[1,2,3],[4,5,6]])arr2=np.array([[7,8,9],[10,11,12]])print(arr1+arr2)print(arr1-arr2)print(arr1*arr2)print(arr1/arr2)print()defbaseOperationByCoefficient():#数组与标量的算术运算会将标量值传播到各个元素,不同大小的数组之间的运算叫做广播。# 类似看作矩阵变为一排,人人有份arr1=np.array([[1,2,3],[4,5,6]])print(arr1+100)print(arr1-100)print(arr1*100)print(arr1/100)# 广播机制是 NumPy 中一个允许在不同形状的数组之间进行元素级运算defbroadcastFun():arr1=np.array([1,2,3])arr2=np.array([[4],[5],[6]])print(arr1.shape)# (3,)一根竹签上串了3颗糖,没有"行"和"列"的概念,就是一条线print(arr2.shape)# 3行1列,二维print(arr1+arr2)''' 广播兼容规则:两个维度相等,或者其中一个是 1,就能广播。 3 和 1 → 1 能扩成 3 ✓;1 和 3 → 1 能扩成 3 ✓ 上述运算步骤细分拆解: 第一步:自动补齐维度(左边补 1) arr1 (3,) → 补齐成 (1, 3) arr2 (3,1) → 保持 (3, 1) 第二步:广播自动扩展成一样大 arr1 从 (1,3) 扩展成 (3,3) 沿着行复制 3 次 [1,2,3] [1,2,3] [1,2,3] arr2 从 (3,1) 扩展成 (3,3) 沿着列复制 3 次 [4,4,4] [5,5,5] [6,6,6] arr1 (1,3) → 纵向复制 3 次 → (3,3) arr2 (3,1) → 横向复制 3 次 → (3,3) ┌───┬───┬───┐ ┌───┬───┬───┐ │ 1 │ 2 │ 3 │ ← 原数据 │ 4 │ 4 │ 4 │ ← 4 横向拷贝 3 份 ├───┼───┼───┤ ← 复制第1行 ├───┼───┼───┤ │ 1 │ 2 │ 3 │ ← 复制第2行 │ 5 │ 5 │ 5 │ ← 5 横向拷贝 3 份 ├───┼───┼───┤ ← 复制第3行 ├───┼───┼───┤ │ 1 │ 2 │ 3 │ │ 6 │ 6 │ 6 │ ← 6 横向拷贝 3 份 └───┴───┴───┘ └───┴───┴───┘ 第三步:逐元素相加 [1,2,3] + [4,4,4] = [5,6,7] [1,2,3] + [5,5,5] = [6,7,8] [1,2,3] + [6,6,6] = [7,8,9] 最终结果 [[5 6 7] [6 7 8] [7 8 9]] 总结 (3,) → 横向扩展,复制行 (3,1) → 纵向扩展,复制列 最后变成同样大小的矩阵,再逐元素相加 广播兼容规则:两个维度相等,或者其中一个是 1,就能广播。 3 和 1 → 1 能扩成 3 ✓; 1 和 3 → 1 能扩成 3 ✓ 从右往左比: 第0维(最右): 3 vs 1 → 1 可以扩展到 3 ✓ 第1维: 1 vs 3 → 1 可以扩展到 3 ✓ '''defbroadcastFunError():# 一维数组arr5=np.array([1,2,3])# 形状为 (3,)# 一维数组arr6=np.array([4,5])# 形状为 (2,)try:result=arr5+arr6print(result)exceptExceptionase:print(f"错误信息(3,) 和 (2,) 完全不兼容,不能运算: \n{e}")''' arr5 维度: (3,) → (3,) arr6 维度: (2,) → (2,) 从右往左比:第0维: 3 vs 2 → 3 ≠ 2,而且谁也不是 1 ✗/(ㄒoㄒ)/~~ 可以想象成要把两个矩阵拉伸成一样尺寸才能对应位置相加: [1,2,3] 是 3 个位置 [4,5] 只有 2 个位置 数量对不上,没法一一配对计算,程序不知道第 3 个数字拿谁去加,所以报错。 '''if__name__=='__main__':baseOperationFun()# baseOperationByCoefficient()# broadcastFun()# broadcastFunError()