Suppose I have the following numpy array:
>>> a=np.zeros(10)
>>> a
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
I can use numpy.ufunc.at to modify that array in place:
>>> np.add.at(a, [0,3], 2)
>>> a
array([ 2., 0., 0., 2., 0., 0., 0., 0., 0., 0.])
If I now try on a matrix, what I assume to be the method does not work:
>>> 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.]])
My expectation based on supplying the list of tuples of [(0,0),(1,1)]
would be:
[[ 2., 0., 0., 0.],
[ 0., 2., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]]
Any suggestions on what I use as a list of indices in numpy.ufunc.at
to get that matrix?
If you want to do multidimensional indexing, you don't pass a list of index tuples; you pass a tuple of index lists (or index arrays).
indices = ([0, 1], [0, 1])
np.add.at(m, indices, 2)
indices[0]
gives all the first coordinates of the cells you want to modify, and indices[1]
gives all the second coordinates. Here's an example:
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.]])
I'm not entirely sure why it works this way. I suppose it might be more convenient once you've gotten the hang of it, or it might make the rules more internally consistent somehow, but I don't have enough experience with multidimensional indexing to say one way or another.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With