给定三个numpy数组:一个多维数组x
,一个向量y
具有尾随单一维度,一个向量z
没有尾随单一维度,
x = np.zeros((M,N))
y = np.zeros((M,1))
z = np.zeros((M,))
广播操作的行为根据矢量表示和上下文而变化:
x[:,0] = y # error cannot broadcast from shape (M,1) into shape (M)
x[:,0] = z # OK
x[:,0] += y # error non-broadcastable output with shape (M) doesn't match
# broadcast shape(M,M)
x[:,0] += z # OK
x - y # OK
x - z # error cannot broadcast from shape (M,N) into shape (M)
我意识到我可以做到以下几点:
x - z[:,None] # OK
但我不明白这个明确的符号是什么给我买的。它当然不会购买可读性。我不明白为什么表达式x - y
没问题,但x - z
是不明确的。
Numpy为什么处理带或不带尾随单一维度的向量?
编辑:documentation说明:两个维度相等时兼容,或者其中一个维度是1 ,但y
和z
是两个函数M x 1
向量,因为M x 0
向量不包含任何元素。
答案 0 :(得分:4)
惯例是广播将在数组的形状开头插入单个维度。这样可以方便地对数组的最后一维执行操作,因此(x.T - z).T
应该可以正常工作。
如果要自动确定x
匹配z
的哪个轴,x - z
这样的操作会导致错误,当且仅当N == M
时,代码更难测试。因此,约定允许一些方便,同时对某些错误具有鲁棒性。
如果你不喜欢z[:, None]
的简写,也许你会发现z[:, np.newaxis]
更清楚。
要使x[:,0] = y
之类的作业生效,您可以使用x[:,0:1] = y
代替。
答案 1 :(得分:0)
使用Numpy 矩阵接口而不是数组接口会产生desired broadcasting behaviours:
x = np.asmatrix(np.zeros((M,N)))
y = np.asmatrix(np.zeros((M,1)))
x[:,0] = y # OK
x[:,0] = y[:,0] # OK
x[:,0] = y[:,0:1] # OK
x[:,0] += y # OK
x - y # OK
x - np.mean(x, axis=0) # OK
x - np.mean(x, axis=1) # OK
答案 2 :(得分:0)
以不同方式处理(M,1)
和(M,)
的一个好处是,您可以指定要对齐的尺寸和要广播的尺寸
说你有:
a = np.arange(4)
b = np.arange(16).reshape(4,4)
# i.e a = array([0, 1, 2, 3])
# i.e b = array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
当您执行c = a + b
时,a
和b
将在axis=1
中对齐,a
将在axis=0
广播:
array([[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]])
但是,如果您想在a
中对齐b
和axis=0
并在axis=1
中进行广播,该怎么办?
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]])
(M,1)
vs (M,)
差异使您可以指定要对齐和广播的维度。
(即如果(M,1)
和(M,)
被视为相同,您如何告诉您想要在axis=1
广播的numpy?)