Numpy:按索引将一个矩阵的行添加到另一个矩阵

3

简而言之,我想要索引矩阵并添加到每一行。

在这个例子中,第一行(由0索引)应该加上[1,1,1]。然后第二行(由1索引)应该加上[2, 2, 2]。最后第一行(由第三个0索引)应该加上[3, 3, 3]

>>> a = np.array([np.array([1,2,3]), np.array([4,5,6])])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])
>>> a[np.array([0,1,0]), :] += np.array([np.array([1,1,1]), np.array([2,2,2]), np.array([3,3,3])])

希望达成的目标:

>>> a
array([[5, 6, 7],
       [6, 7, 8]])

实际的:

>>> a
array([[4, 5, 6],
       [6, 7, 8]])

编辑2:

根据下面的评论,解决方案运行缓慢。在我只是添加0来测试速度的代码段中:

print y.shape
print dW.shape
np.add.at(dW, (y, slice(None)), 0)

输出:

(49000,)
(10, 3073)

没有np.add.at这一行,剩余的代码只需要大约1秒钟。如果加上np.add.at,则需要约21秒钟。 y.npy dW.npy


1
你能口头解释一下你的添加应该意味着什么吗?实际上,在你的赋值中,你试图两次替换第0行,所以我认为这有点难以理解。 - Marcus Müller
1
完成了!如果需要进一步澄清,请告诉我。 - ibash
请在你的代码中充分记录这一点,否则它将成为一个潜在的 bug/feature。 - hpaulj
1个回答

7
这是一个已知的 numpy 问题,这里有很好的解释:这里
例如, a[[0,0]] += 1 只会增加第一个元素一次,因为缓存,而 add.at(a, [0,0], 1) 会将第一个元素增加两次。 numpy 使用 add.at() 解决了这个问题。例如:
a = array([1,2,3])
add.at(a,[0,0],4) # now a = array([9, 2, 3])

在这种情况下,我们希望它适用于多维数组:
a = np.array([np.array([1,2,3]), np.array([4,5,6])])
np.add.at(a,([0,1,0],slice(None)),array([[1,1,1],[2,2,2],[3,3,3]]))

结果是:

array([[5, 6, 7], [6, 7, 8]])

我猜您将 "7" 错误地输入成了 "6"。

谢谢你!你让我摆脱了困境! - ibash
有没有以向量化的方式来完成这个操作的方法? - ibash
这是向量化的方式。 - gg349
1
哦,我在实现中使用了这个,但它比仅使用循环慢了5倍。可能是因为slice(None)——我还在熟悉numpy,这是必要的吗? - ibash
这很有趣。是的,可能是因为操作在二维数组上。而且我认为你确实需要切片。请发一个例子,以便我们可以处理它。 - gg349
我添加了代码并附上了y.npy和dW.npy文件以进行复现。感谢所有的帮助! - ibash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接