Python numpy index is out of bound for axis zero - python

I have a code written in Python similar to the following:
def adamic_adar_prediction(graph):
adjacencyMatrix = graph.get_adjacency()
AAMatrix = adamic_adar_score(graph)
AAMatrix = np.array(AAMatrix)
i = (-AAMatrix ).argsort(axis=None, kind='mergesort')
j = np.unravel_index(i, AAMatrix .shape)
sortedList = np.vstack(j).T
print(sortedList.size)
print(sortedList[1658943])
print(sortedList[1658945])
While the result of the first print is 3,316,888 I receive the following error for the last print:
IndexError: index 1658944 is out of bounds for axis 0 with size 1658944
Any idea why this error arises for my array?

You don't have enough elements in your array, for example:
In [5]: import numpy as np
In [6]: a = np.array([1,2])
In [8]: a[2] # there is no element at 2nd index
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-8-016a87a854bc> in <module>()
----> 1 a[2]
IndexError: index 2 is out of bounds for axis 0 with size 2

Considering how mysterious your problem is, I'd go ahead and test this with a try/except loop to be sure the code goes past that point and is only having issues at index 1658944...
something like:
for x in range(sortedList.size):
try:
sortedList[x]
except:
print "no index at", x
Report back what your results are.

Thanks for all of the comments. I figured my problem is that sortedList.size returns total number of elements in the array while I was expecting the number of tuples in my array (since sortedList is a list of tuples [[],[],...]). So I solved my problem using sortedList.shape

Related

I cannot really tell what is out of range

I keep getting this error and I don't even know what is wrong, so what happens is I get some random indexes from the array temp which holds only integers from 0 to the len(students_grades) after that I go to the students_grades and get the value of the indexes I just got and store it in the object called cluster-> have two attributes (centroid and individuals)
What I want to do is the following, I want to generate some random indexes from the array temp and then take those indexes and go get their values from the array students_grades and then I want to remove that index from students_grades ..can someone help?
data = pd.read_csv("CourseEvaluation.csv", header=None)
students_grades = []
for i in range(1, 151):
students_grades.append([float(data.values[i, j]) for j in range(1, 21)])
k = int(input("enter how many clusters :"))
indices = numpy.random.choice(temp, k, False)
initial_clusters = []
for i in range(0, len(indices)):
print("product number:", indices[i] + 1)
cluster = Cluster(students_grades[indices[i]],
students_grades[indices[i]])
students_grades.pop(indices[i])
initial_clusters.append(cluster)
Error:
Traceback (most recent call last):
File "", line 103, in <module>
cluster = Cluster(students_grades[indices[i]], students_grades[indices[i]])
IndexError: list index out of range
You might want to reorganise your code a bit ;-)
Any way, I can't be a hundred percent sure, but I'm guessing your problem is the following: you're making an array of random indices, named indices, with potentially largest value temp - 1, which might occur at any point in that array (but only once):
indices = numpy.random.choice(temp, k, False)
Next you loop over those indices, and at every step you're reducing the size of your students_grades list:
students_grades.pop(indices[i])
So assuming that temp = len(students_grades) at the start of this, after i steps the length of students_grades is only temp - i, but the index you are getting from your indexes array can be as high as temp - 1 so you can get index out of bound errors.
To remedy this, remember that
indices = numpy.random.choice(temp, k, False)
means that you won't get the same index twice, so it isn't necessary to remove the value at the index from students_grades.
BTW just some general python style advise: instead of
for i in range(len(some_list)):
stuff with some_list[i]
you can use
for element in some_list:
stuff with element
for more readable, 'pythonic', code ;-)

How to randomly change boolean value in a list

I'm trying to randomly assign a 'True' value to a list of booleans. When I run the code, I keep getting an error. Here's the code:
for x in population:
if x:
r = random.randint(0, len(population))
population[r] = True
Which keeps throwing the error:
"Traceback (most recent call last):
population[r] = True
IndexError: list assignment index out of range"
I'm sure it's something trivial, but I can't figure it out. How is the index assignment out of range when I constrain it to within the length of the list?
random.randint(a, b) returns a number between a and b inclusive. If the result of the function call equals len(population), then you're trying to do population[len(population)], which will raise an IndexError because indexing starts at 0.
Simple change: Just minus 1 from len(population):
r = random.randint(0, len(population)-1)
Or use randrange(a, b), which is not inclusive:
r = random.randrange(len(population))
Note that if the first argument is 0 we don't need it since it will assume the start is 0.
According to the documentation, random.randint(a, b)
Return a random integer N such that a <= N <= b.
Since arrays are indexed starting at 0 in Python, len(population) is outside the range of the array (hence your error). As #TerryA indicated, you actually want the range to be from 0 to len(population) - 1.
try :
for x in population:
if x:
r = random.randint(0, len(population)-1)
population[r] = True

lndexError: list index out of range

I need to generate a string from random letters given in list take_from. The first time the function was executed it generated a phrase but all my following tries prompted an error "list index out of range". I can`t understand this error in my case and I tried while loop instead of for loop but it did not work either.
from random import randint
def make_a_phrase():
random_string = ''
take_from = ['a','b','c','d','e','f','g','h','i','j','k','l',
'm','n','o','p','q','r','s','t','v','u','w','x',
'y','z',' ']
for i in range(28):
random_string = random_string + take_from[randint
(0,len(take_from))]
return random_string
From the docs
random.randint(a, b)
Return a random integer N such that a <= N <= b.
Alias for randrange(a, b+1).
Therefore you can get values from 0 to len(take_from) - inclusive the endpoints - which in case of the upper bound would be out of list's index range as it is zero based and as such only has len(take_from) - 1 elements
In Python, lists are indexed with integers ranging from 0 to 1 less than the length of the list. E.g., a list with 10 items in it would have indexes from 0 to 9.
Your call to randint() attempts to get indexes from zero to the full length of the list, which will cause this exception. Change it to:
for i in range(28):
random_string = random_string + take_from[randint
(0,len(take_from)-1)]
The reason this happens, is because the len returns the length, but the last index is always the length - 1 (since indices start from 0).
So eventually, the random integer that comes up is the length, and of course, there is no element at that number.
Here is a simple example:
>>> i = [1,2,3]
>>> len(i)
3
>>> i[len(i)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
However, if you -1 from the length you will get the last item:
>>> i[len(i)-1]
3
You should change your loop to say:
for i in range(0, len(take_from)):
You are currently experiencing an off-by-one error because you only have 27 elements in your list, not 28.
You could try something like this instead
from string import ascii_lowercase
import random
def make_a_phrase():
return ''.join(random.choice(ascii_lowercase + ' ') for i in range(28))

Indexing error scanning list

I apologize ahead of time for the basic nature of this question but I could really use a different set of eyes to see why I'm still getting an IndexError: list index out of range.
Here is my code:
def longestRun(L):
counter=1
ii=0
counts=[1]
while ii<=max(range((len(L)))):
if L[ii] <= L[(ii+1)]:
counter+=1
ii+=1
else:
ii+=1
counts.append(counter)
counter=1
continue
counts.sort()
return counts[-1]
It is supposed to count the longest streak of consecutive increases for a list of integers. I got it working by subtracting 1 from the while statement but then it will not always show the right answer because it won't go through the whole list.
Here is my specific error message:
IndexError
Traceback (most recent call last)
<ipython-input-76-1b4664f2fb31> in <module>()
----> 1 longestRun(L)
C:\Users\james_000\Desktop\longestRun.py in longestRun(L)
4 counts=[1]
5 while ii<=max(range((len(L)))):
----> 6 if L[ii] <= L[(ii+1)]:
7 counter+=1
8 ii+=1
Your while loop is while ii<=max(range((len(L)))): and then your if statement's condition accesses L[ii+1] which runs off the end of the array.
It's simple math. Let's say L is of length 10. That makes the last index 9. ii can eventually be 9, thus ii+1 is going to be out of range.

Using for loop to iterate two variables together

How do I go about doing something like this?
Say I have an array x = np.array([1,2,3,4,5]) of length 5,
for i,j in range(len(x)):
I want i and j to increment together.
This is throwing me an error message:
TypeError Traceback (most recent call last)
<ipython-input-4-37d0ddc3decf> in <module>()
----> 1 for i,j in range(len(x)):
2 print i,j
3
TypeError: only length-1 arrays can be converted to Python scalars
The reason I need this is because I have to use it in a condition inside the for loop. Like say, y[i][j] and I want this to be 0,0 then 1,1 and so on.
Why do you need j in the first place? If j is always equal to i, just use i. No need for a second variable.
Edited answer
OP says
The reason I need this is because I have to use it in a condition inside the for loop. Like say, y[i][j] and I want this to be 0,0 then 1,1 and so on.
In that case, you could simply use:
y[i][i]
Original answer
I'm not really sure why you would want to do that, you could just set it in the first line of the for loop:
for i in range(len(x)):
j = i
... #rest of the code follows
You could also use enumerate, as pointed in comments by #Julien, like below (but IMO, the earlier method is better):
>>> for i, j in enumerate(xrange(len(x))):
... print i, j
...
0 0
1 1
2 2
You could try this:
for i, j in zip(range(len(x)), range(len(x))):
print i, j
So the question is about how to iterate two variables, not why ;-)

Categories