Home > Software engineering >  A question about numpy "at" function indexation
A question about numpy "at" function indexation

Time:12-22

I am trying to use this library to compute phase transfer entropy. Long story short, it keeps throwing index-out-of-bounds exception, I isolated a piece of code that does it and it looks pretty much like this:

import numpy as np 

idx1 = np.array([7, 6, 6, 6, 5, 5, 5, 6, 7, 5, 5, 7, 8, 5, 5, 5, 8, 4, 6, 7, 7, 8, 6, 7, 5, 6, 5, 4, 5, 6, 6, 7, 7, 6, 6, 6, 5, 6, 7, 7, 6, 7, 7, 7, 5, 6, 8, 6])
idx2 = np.array([7, 7, 7, 6, 6, 5, 5, 6, 7, 5, 5, 7, 9, 6, 4, 5, 8, 4, 6, 7, 6, 8, 6, 7, 5, 6, 4, 5, 6, 5, 5, 7, 6, 5, 6, 5, 6, 6, 7, 7, 6, 7, 8, 7, 5, 6, 8, 6])

arr = np.zeros([idx1.max() 1, idx2.max() 1])
arr_via_for = np.zeros([idx1.max() 1, idx2.max() 1])

for i, j in zip(idx1, idx2):
    arr_via_for[i, j]  = 1
    
np.add.at(arr, [idx1, idx2], 1)

What I expect is that arr and arr_via_for should be exactly the same, but they apparently are not, the line

np.add.at(arr, [idx1, idx2], 1)

throws an exception "IndexError: index 9 is out of bounds for axis 0 with size 9" and I cannot find out why. It feels pretty much like I'm missing something really obvious about indexation, but what exactly am I doing wrong?

CodePudding user response:

hpaulj is right (thanks for the help!), the "at" function requires a tuple of arrays instead of an array of arrays in case of the multidimensional first operand. I changed

np.add.at(arr, [idx1, idx2], 1)

to

np.add.at(arr, (idx1, idx2), 1)

and it works fine now, and arr and arr_via_for are equal. I did not check it, but I guess the reason was that "array-of-arrays" indexation worked earlier (as FBruzzesi mentioned in comments for 1.19.1 numpy) and do not work now (for 1.23.5, at least). The library I am using was written 4 years ago, so I will just change its code a little bit and hope it works.

CodePudding user response:

In most programming languages, array objects index is start from 0, end with the size of the object minus 1. In Python, the error or message or warning state that the size of some arrays or vectors end up with size n, but actually you can access to the last item of the list by LIST[(n - 1)].

>>> list_ = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
>>> # Size of the list
>>> len(list)
9
>>> list_[0]
1
>>> list_[1]
2
>>> list_[8]
9
>>> list_[9]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Same to your numpy object. array_[(array_.index("last-item"))] != array_[(len(array_))]

CodePudding user response:

arr = np.array([2,3,4])
np.add.at(arr, [0,1,1,2], 1)
print(arr)
Output:
[3 5 4]

The second argument in my case [0,1,1,2] can't have number 3, as there is no index 3 avaiable in the arr variable.

The above example will add 1 to the number as per index number.

  • Related