数组的广播机制
Numpy可以转换这些形状不同的数组,使它们都具有相同的大小,然后再对它们进行运算。下面是广播示意图:

术语广播是指 NumPy 在算术运算期间处理不同形状的数组的能力。对数组的算术运算通常在 相应的元素上进行。如果两个阵列具有完全相同的形状,则这些操作被无缝执行。
如果两个数组的维数不相同,则元素到元素的操作是不可能的。然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。
如果满足以下条件之一,那么数组被称为可广播的。
广播的规则:
实例:
import numpy as np
# 形状相同的广播
a = np.ones((3, 3))
print(a)
print(a.ndim)
print(a.shape)
print(a+a)
# 相同维度,但其中某一个或多个维度长度为 1 的广播:
b = np.arange(3).reshape(1, 3)
print(b)
print(b.ndim)
print(b.shape)
print(a+b)
c = np.arange(3).reshape(3, 1)
print(c)
print(c.ndim)
print(c.shape)
print(a+c)
# 较少的维度,默认在其前面追加长度为1的维度
d = np.arange(3)
print(d)
print(d.ndim)
print(d.shape)
print(a+d)
# 如果是标量的话,会广播整个数组上
print(a*3)
print(b*3)
print(c*3)
arr1 = np.arange(0, 40, 10)
print(arr1)
print(arr1.shape)
arr2 = np.array([0, 1, 2])
print(arr2)
print(arr2.shape)
#将数组arr1转换为4行1列
arr1=arr1[:,np.newaxis]
print(arr1)
print(arr1.shape)
#数组arr1+arr2,并查看形状
print(arr1+arr2)
print((arr1+arr2).shape)
#现在尝试模拟一个广播的方式, 把arr1中的每个元素拉长三倍
arr1=np.concatenate([arr1,arr1,arr1],axis=1)
print(arr1)
#arr2中的元素拉长4倍
arr2=np.concatenate([arr2,arr2,arr2,arr2]).reshape(4,-1)
print(arr2)
#arr1+arr2
print(arr1+arr2)
#这里我们就能看出,我们将数组扩展到较大的维度再进行通用函数操作,和我们直接进行广播操作结果是一样的。
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
2
(3, 3)
[[2. 2. 2.]
[2. 2. 2.]
[2. 2. 2.]]
[[0 1 2]]
2
(1, 3)
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
[[0]
[1]
[2]]
2
(3, 1)
[[1. 1. 1.]
[2. 2. 2.]
[3. 3. 3.]]
[0 1 2]
1
(3,)
[[1. 2. 3.]
[1. 2. 3.]
[1. 2. 3.]]
[[3. 3. 3.]
[3. 3. 3.]
[3. 3. 3.]]
[[0 3 6]]
[[0]
[3]
[6]]
[ 0 10 20 30]
(4,)
[0 1 2]
(3,)
[[ 0]
[10]
[20]
[30]]
(4, 1)
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
(4, 3)
[[ 0 0 0]
[10 10 10]
[20 20 20]
[30 30 30]]
[[0 1 2]
[0 1 2]
[0 1 2]
[0 1 2]]
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
import numpy as np
#生成3行5列 值为0-5随机整数的数组
a1 = np.random.randint(0,5,size=(3,5))
print(a1)
#数组中的所有元素都乘2
print(a1*2)
#数组中所有的元素只保留2位小数
a2 =np.random.random((3,3))
print(a2)
print(a2.round(2))
[[1 2 0 0 1]
[0 0 2 0 4]
[0 3 4 0 4]]
[[2 4 0 0 2]
[0 0 4 0 8]
[0 6 8 0 8]]
[[0.23908068 0.47164088 0.02494872]
[0.11508108 0.67393144 0.27543608]
[0.93289384 0.0030417 0.78057539]]
[[0.24 0.47 0.02]
[0.12 0.67 0.28]
[0.93 0. 0.78]]
#数组形状一致时 各个元素相加减(满足数组广播机制)
a1 = np.random.randint(0,5,size=(3,5))
a2 = np.random.randint(0,5,size=(3,5))
print(a1)
print(a2)
print(a1+a2)
#形状不一致的数组不能相加减(不满足数组广播机制)
a3 = np.random.randint(0,5,size=(3,4))
print(a3)
#a1+a3 报错
#print(a1+a3)
#两个数组行数相同 ,其中一个数组列数为1(满足数组广播机制)
a4 = np.random.randint(0,5,size=(3,1))
print(a4)
print(a1+a4)
#两个数组列数相同 ,其中一个数组行数为1(满足数组广播机制)
a5 = np.random.randint(0,5,size=(1,5))
print(a5)
print(a1+a5)
[[2 1 3 4 0]
[1 2 0 0 2]
[0 0 3 1 4]]
[[2 0 0 1 2]
[3 2 2 1 1]
[2 1 4 2 4]]
[[4 1 3 5 2]
[4 4 2 1 3]
[2 1 7 3 8]]
[[2 4 1 3]
[4 4 2 2]
[1 1 3 0]]
[[3]
[4]
[0]]
[[5 4 6 7 3]
[5 6 4 4 6]
[0 0 3 1 4]]
[[0 3 0 4 1]]
[[2 4 3 8 1]
[1 5 0 4 3]
[0 3 3 5 5]]
小结: 1. 数组和数字直接进行运算是没有问题的。 2. 两个shape相同的数组是可以进行运算的。 3. 如果两个shape不同的数组,想要进行运算,那么需要看它们是否满足广播原则。