【问题标题】:numpy broadcast addition along arbitrary axes沿任意轴的 numpy 广播加法
【发布时间】:2018-11-09 07:12:22
【问题描述】:

我想通过简单地沿一个或多个轴执行相同的加法来添加两个不同维度的数组。

非矢量化解决方案:

x = np.array([[[1,2],[3,4],[5,6]],[[7,8],[9,0],[1,2]],[[3,4],[5,6],[7,8]],[[9,0],[1,2],[3,4]]]) #shape (4,3,2)
y = np.array([[1,2],[3,4],[5,6],[7,8]]) #shape (4,2)

ans = np.copy(x)
for i in range(x.shape[1]):
    ans[:,i] += y

print(ans) #shape (4,3,2)

我怎样才能沿着(例如)第二个轴广播这个?更一般地说,我怎样才能使这个广播沿任意轴?

【问题讨论】:

  • 要将 yx 一起使用,您必须将其重塑为 (4,1,2)。广播规则有据可查。
  • 你可以使用 repmat 或 tile 吗?
  • 你只想广播一个维度吗?或者其中一个数组可以比另一个数组大 1 维以上?
  • 这显然是stackoverflow.com/questions/53216750/numpy-add-along-first-axis 的续集。 y 是 (3,2),所以广播需要 (1,3,2) 形状,这是自动的。

标签: python numpy


【解决方案1】:

看两个数组的形状:

>>> x.shape
(4, 3, 2)
>>> y.shape
(4, 2)

您会在此处看到添加需要沿第 0 轴和最后一个轴进行广播。一个简单的选择是

>>> x + y[:, None, :] 
array([[[ 2,  4],
        [ 4,  6],
        [ 6,  8]],

       [[10, 12],
        [12,  4],
        [ 4,  6]],

       [[ 8, 10],
        [10, 12],
        [12, 14]],

       [[16,  8],
        [ 8, 10],
        [10, 12]]])

在哪里,

>>> y[:, None, :].shape
(4, 1, 2)

这实际上只是改变了y 的步幅,因此可以广播添加。


更好的是,按照 hpaulj 在 cmets 中的建议使用 np.expand_dims,这会增加一个额外的倒数第二个维度,所以你可以这样做

>>> x + np.expand_dims(y, 1)
array([[[ 2,  4],
        [ 4,  6],
        [ 6,  8]],

       [[10, 12],
        [12,  4],
        [ 4,  6]],

       [[ 8, 10],
        [10, 12],
        [12, 14]],

       [[16,  8],
        [ 8, 10],
        [10, 12]]])

【讨论】:

  • 我认为这个答案是正确的,如果需要,OP 可以使用多个 None。除非他正在寻找一个能够发现相似维度然后调整广播的通用函数。
  • 他之前的问题是关于添加一个(3,2)数组;所以他可能确实是专注于‘武断’。无论如何,通常的做法是根据需要添加None 维度。广播规则经过精心设计,可避免出现模棱两可的情况。
  • @anishtain4:在我看来,“发现”相似的维度有点“危险”,因为它可能“发生”两个维度具有相同的大小,但这本身并不意味着这些“语义上”是相同的。因此,这可能会导致一个经常工作的函数,但时不时会出现意外行为。
猜你喜欢
  • 2012-08-29
  • 2019-10-29
  • 2018-09-01
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
相关资源
最近更新 更多