今天,我们来接着了解NumPy
现在,我们来了解一下Broadcasting(广播)
广播是一种强大的机制,允许NumPy在执行算术运算的时候使用不同形状的数组,比如,我们经常有一个较小的数组
和一个较大的数组,我们希望多次使用较小的数组对较大的数组进行操作
例如 假设我们想要向矩阵的每一行加一个常量向量
import numpy as np
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
v = np.array([1,0,1])
y = np.empty_like(x) #创建一个空的y数组 类型和x一样
for i in range(4)
y[i,:] =x[i,:] +v
print(y) #打印 [[2 2 4],
# [5 5 7],
# [8 8 10],
# [11 11 13]]
这有效; 但是当矩阵x非常大时,在Python中计算显式循环可能会很慢。请注意,将向量添加v到矩阵的每一行 x等同于
vv通过堆叠多个v垂直副本来形成矩阵,然后执行和的元素x和求和vv。我们可以像这样实现这种方法:
import numpy as np
# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1)) # Stack 4 copies of v on top of each other
print(vv) # Prints "[[1 0 1]
# [1 0 1]
# [1 0 1]
# [1 0 1]]"
y = x + vv # Add x and vv elementwise
print(y) # Prints "[[ 2 2 4
# [ 5 5 7]
# [ 8 8 10]
# [11 11 13]]"
Numpy广播允许我们执行此计算而无需实际创建多个副本v。考虑这个版本,使用广播:
import numpy as np
# We will add the vector v to each row of the matrix x,
# storing the result in the matrix y
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v # Add v to each row of x using broadcasting
print(y) # Prints "[[ 2 2 4]
# [ 5 5 7]
# [ 8 8 10]
# [11 11 13]]"
Broadcasting two arrays together follows these rules:
- If the arrays do not have the same rank, prepend the shape of the lower rank array with 1s until both shapes
have the same length. - The two arrays are said to be compatible in a dimension if they have the same size in the dimension, or
if one of the arrays has size 1 in that dimension. - The arrays can be broadcast together if they are compatible in all dimensions.
- After broadcasting, each array behaves as if it had shape equal to the elementwise maximum of shapes
of the two input arrays. - In any dimension where one array had size 1 and the other array had size greater than 1, the first array
behaves as if it were copied along that dimension
翻译过来大概就是(以下是我的理解)
1. 如果两个矩阵的长度不一,就让长度短的矩阵+1,一直加到二者的长度一样
2. 如果两个数组在维度中具有相同的大小,或者如果其中一个数组在该维度中具有大小1,则称这两个数组在维度上
是兼容的。
3. 如果阵列在所有维度上兼容,则可以一起广播。
4. 在广播之后,每个阵列的行为就好像它的形状等于两个输入数组的形状的元素最大值。
5. 在一个数组的大小为1且另一个数组的大小大于1的任何维度中,第一个数组的行为就像沿着该维度复制一样
下面是广播中的一些方法
import numpy as np
# Compute outer product of vectors
v = np.array([1,2,3]) # v has shape (3,)
w = np.array([4,5]) # w has shape (2,)
# To compute an outer product, we first reshape v to be a column
# vector of shape (3, 1); we can then broadcast it against w to yield
# an output of shape (3, 2), which is the outer product of v and w:
# [[ 4 5]
# [ 8 10]
# [12 15]]
print(np.reshape(v, (3, 1)) * w)
# Add a vector to each row of a matrix
x = np.array([[1,2,3], [4,5,6]])
# x has shape (2, 3) and v has shape (3,) so they broadcast to (2, 3),
# giving the following matrix:
# [[2 4 6]
# [5 7 9]]
print(x + v)
# Add a vector to each column of a matrix
# x has shape (2, 3) and w has shape (2,).
# If we transpose x then it has shape (3, 2) and can be broadcast
# against w to yield a result of shape (3, 2); transposing this result
# yields the final result of shape (2, 3) which is the matrix x with
# the vector w added to each column. Gives the following matrix:
# [[ 5 6 7]
# [ 9 10 11]]
print((x.T + w).T)
# Another solution is to reshape w to be a column vector of shape (2, 1);
# we can then broadcast it directly against x to produce the same
# output.
print(x + np.reshape(w, (2, 1)))
# Multiply a matrix by a constant:
# x has shape (2, 3). Numpy treats scalars as arrays of shape ();
# these can be broadcast together to shape (2, 3), producing the
# following array:
# [[ 2 4 6]
# [ 8 10 12]]
print(x * 2)
广播的作用,是你的代码看起来更加简洁
心得 广播确实是我以前没有接触过的新事物,确实了解到了许多