numpy
的广播计算是指在多维数组上进行的一种高效计算方式。
它可以将计算任务分配到每个维度上,并且可以在计算过程中进行数据共享和同步,从而提高计算效率和精度。
广播计算在数值计算、科学计算、机器学习等领域都有广泛的应用。
例如,在数值计算中,广播计算可以用于求解大规模的非线性方程组;在科学计算中,广播计算可以用于模拟和预测自然现象;在机器学习中,广播计算可以用于分布式训练和推理等场景。
numpy
中广播计算遵循3个严格的规则:
-
如果两个数组的维度数不相同,小维度数组的形状将会在最左边补
1
-
如果两个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度为
1
的维度扩展以匹配另一个数组的形状 -
如果两个数组的形状在任何一个维度上都不匹配并且没有任何一个维度等于
1
,那么会引发异常
广播规则一
比如一维数组和数字运算:
import numpy as np
arr = np.random.randint(1, 10, 5)
print(arr)
#运行结果
[9 8 2 9 7]
print(arr + 1)
#运行结果
[10 9 3 10 8]
print(arr * 2)
#运行结果
[18 16 4 18 14]
arr+1
时,1
被自动扩充成[1, 1, 1, 1, 1]
,和 arr
一样结构的数组。
arr*2
时,同样,2
被自动扩充成[2, 2, 2, 2, 2]
,和 arr
一样结构的数组。
二维数组和一维数组运算时:
arr1 = np.random.randint(1, 10, (3, 3))
print(arr1)
#运行结果
[[4 4 3]
[8 2 1]
[5 6 5]]
arr2 = np.random.randint(1, 10, 3)
print(arr2)
#运行结果
[3 9 2]
print(arr1 + arr2)
#运行结果
[[ 7 13 5]
[11 11 3]
[ 8 15 7]]
这种情况下,arr2
和arr1
一样,都是3
列,只是行数不一样,所以被自动扩展成:
[[3 9 2]
[3 9 2]
[3 9 2]]
然后再和arr1
对应的位置进行加法运算。
广播规则二
规则二两个数组每个维度上的数量都不一样,比如如下两个二维数组的运算:
arr1 = np.random.randint(1, 10, (1, 3))
print(arr1)
#运行结果
[[6 6 7]]
arr2 = np.random.randint(1, 10, (3, 1))
print(arr2)
#运行结果
[[7]
[6]
[2]]
print(arr1 + arr2)
#运行结果
[[13 13 14]
[12 12 13]
[ 8 8 9]]
arr1
是1
行3
列的数组,所以arr1
自动扩充了行,保持和arr2
一致:
[[6 6 7]
[6 6 7]
[6 6 7]]
arr2
是3
行1
列的数组,所以arr2
自动扩充了列,保持和arr1
一致:
[[7 7 7]
[6 6 6]
[2 2 2]]
然后 arr1+arr2
得出了上面的结果。
广播规则三
规则三也是两个维度不一样的数组,只不过在不一样的那个维度上,它们的维度数都不是1
。
比如:
arr1 = np.random.randint(1, 10, (2, 3))
print(arr1)
#运行结果
[[7 9 3]
[1 8 7]]
arr2 = np.random.randint(1, 10, (3, 1))
print(arr2)
#运行结果
[[8]
[6]
[7]]
print(arr1 + arr2)
#运行结果
#ValueError: operands could not be broadcast together with shapes (2,3) (3,1)
arr1
是2
行3
列的数组,arr2
是3
行1
列的数组。
运算时,arr2
是可以扩充成3
列的,但是arr1
无法扩充成3
行,因为arr1
行的维度和arr2
虽然不一样但不等于1
。
总结回顾
numpy
的广播计算虽然简单,但是对我们的数据分析却很有意义:
- 提高计算效率:广播计算可以将计算任务分配到每个维度上,从而减少计算时间,提高计算效率。
- 减少内存占用:广播计算可以在多个维度上同时进行计算,从而减少需要存储的数据量,减少内存占用。
-
支持并行计算:
numpy
的广播计算可以支持多线程和多GPU并行计算,从而提高计算速度。 -
易于并发编程:
numpy
的广播计算提供了一种并发编程的方式,可以方便地实现多线程和多GPU并行计算。