我正在尝试在另一个库中复制numpy行为。我的图书馆缺少的一件事是广播行为。运算符的广播行为已在numpy中使用documentation stating:
的非赋值运算符很好地定义了[在两个数组上进行操作时,NumPy比较它们的形状在元素方面。它始于尾随尺寸,前进的道路。当
时,两个维度兼容
- 它们相等,或
- 其中一个是1
易于使用* b,但是a * = b或a [:] = b呢? numpy中的分配似乎遵循广播规则的some,即:
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
a = a.reshape(3,1,1,3)
b = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = b.reshape(1,1,3,3)
c = a * b # works!
a *= b # fails, non-broadcastable output operand with shape (1,1,3,3) doesn't match the broadcast shape (3,1,1,3)
a[:] = b #fails, could not broadcast input array from shape (1,1,3,3) into to shape (3,1,1,3)
b[:,:,:] = a[1,0,0,:] # works!
现在,我可以直观地理解一些规则,为什么对于某些分配却没有意义。问题是,我认为没有规则集可以总体上管理广播。我认为这与输出位置形状匹配有关,尽管在上一个工作示例中(即使没有)逻辑也失败了。我能找到的最接近的东西是单个statement in the docs(强调我的意思):
如前所述,可以使用单个索引,切片以及索引和掩码数组。价值是分配给索引数组的形状必须一致(相同形状或可广播到索引产生的形状)。例如,它是允许为切片分配常量:
这里的“可广播到形状”的定义是什么?
((1,1,3,3)变成形状(3,1,1,3)] >>
b
形状为(1,1,3,3)可以广播到(3,1,3,3),但不能广播到(3,1,1,3)。第三个暗度为3
,不能更改为1
。
[做a*=
和a[:]=
时,a
的形状不变。
[a[1,0,0,:]
是(1,1,3),可以广播到(1,1,1,3)并继续广播到(1,1,3,3)。
使用c = a*b
,广播是:
(3,1,1,3) * (1,1,3,3) => (3,1,3,3)
a
的一个暗度增加到3,b
的另一个暗度也增加到3。对于二进制运算符*
,两个参数都被广播。在分配中,只有RHS。