Numpy广播切片阵列和向量

时间:2014-03-05 02:13:49

标签: python numpy

给定三个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 ,但yz是两个函数M x 1向量,因为M x 0向量不包含任何元素。

3 个答案:

答案 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时,ab将在axis=1中对齐,a将在axis=0广播:

array([[0, 1, 2, 3],
   [0, 1, 2, 3],
   [0, 1, 2, 3],
   [0, 1, 2, 3]])

但是,如果您想在a中对齐baxis=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?)