在矩阵上使用ufunc.at

时间:2015-04-14 00:35:38

标签: python numpy

假设我有以下numpy数组:

>>> a=np.zeros(10)
>>> a
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

我可以使用numpy.ufunc.at来修改该数组:

>>> np.add.at(a, [0,3], 2)
>>> a
array([ 2.,  0.,  0.,  2.,  0.,  0.,  0.,  0.,  0.,  0.])

如果我现在尝试使用矩阵,我认为该方法不起作用:

>>> m=np.zeros(16).reshape(4,4)
>>> m
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> np.add.at(m, [(0,0),(1,1)], 2)
>>> m
array([[ 0.,  4.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

我基于提供[(0,0),(1,1)]元组列表的期望是:

      [[ 2.,  0.,  0.,  0.],
       [ 0.,  2.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]]

关于我在numpy.ufunc.at中使用哪些索引列表来获取该矩阵的任何建议?

1 个答案:

答案 0 :(得分:7)

如果要进行多维索引,则不要传递索引元组列表;你传递一个索引列表(或索引数组)的元组。

indices = ([0, 1], [0, 1])
np.add.at(m, indices, 2)

indices[0]给出了要修改的单元格的所有第一个坐标,indices[1]给出了所有第二个坐标。这是一个例子:

In [10]: a = numpy.zeros([4, 4])
In [11]: a
Out[11]: 
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
In [12]: indices = ([0, 3], [2, 1])
In [13]: numpy.add.at(a, indices, 2)
In [14]: a
Out[14]: 
array([[ 0.,  0.,  2.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  2.,  0.,  0.]])

我不完全确定它为什么会这样运作。我想,一旦你掌握了它可能会更方便,或者它可能会使规则在某种程度上更加内部一致,但我没有足够的多维索引经验来说明这种或那种方式。