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 ;-)
Related
I am trying to write a program which iterates i,j and k,and finds the minimum value given a certain formula (vik + vkj - vij), where v is a 2d list of distances between points, k is a new point two be inserted into the new array and i,j are existing values in the new array.
Sorry if this explanation is a little confusing...
My code is this:
values = [[0,2],[3,3],[4,5],[2,1],[7,1]]
points = [0,1,2,3,4]
new = [2,4]
for k in points: #k is the point that will be inserted
minVal = 1000000000000000 #set to any arbitrarily high value, that will be larger than any other distance
for i,j in new:
nextVal = values[i][k] + values[k][j] - values[i][j] # finds value which minimises vik + vkj - vij
if nextVal < minVal:
minVal = nextVal
idx = i #saves index of i,j that gave minimal value, so that k can be inserted between these
jdx = j
new.insert(idx + 1, k) #insert after idx or before jdx
Anyway the probem is I get:
for i,j in new:
TypeError: 'int' object is not iterable
I read somewhere that this is because objects of type int can't be iterated, but I don't get how else to solve this.
How can I have two separate values iterate through a list of ints, while making sure I remember which two values of i,j gave the minimum value, so I can then add k in between them?
I don't fully understand the description of what you're aiming to do, but I can solve this error for you. It's in the line of code:
for i,j in new:
You have defined new as the list [2,4]. So when you do for i,j in [2,4], Python automatically unpacks the list and now you have for i,j in 2,4, which of course can't be iterated. It is forbidden to do something like:
for i in 2:
a=[2, 1, 3, 5, 3, 2]
def firstDuplicate(a):
for i in range(0,len(a)):
for j in range(i+1,len(a)):
while a[i]==a[j]:
num=[j]
break
print(num)
print(firstDuplicate(a))
The output should be coming as 4 and 5 but it's coming as 4 only
You can find the indices of all duplicates in an array in O(n) time and O(1) extra space with something like the following:
def get_duplicate_indices(arr):
inds = []
for i, val in enumerate(arr):
val = abs(val)
if arr[val] >= 0:
arr[val] = -arr[val]
else:
inds.append(i)
return inds
get_duplicate_indices(a)
[4, 5]
Note that this will modify the array in place! If you want to keep your input array un-modified, replace the first few lines in the above with:
def get_duplicate_indices(a):
arr = a.copy() # so we don't modify in place. Drawback is it's not O(n) extra space
inds = []
for i, val in enumerate(a):
# ...
Essentially this uses the sign of each element in the array as an indicator of whether a number has been seen before. If we come across a negative value, it means the number we reached has been seen before, so we append the number's index to our list of already-seen indices.
Note that this can run into trouble if the values in the array are larger than the length of the array, but in this case we just extend the working array to be the same length as whatever the maximum value is in the input. Easy peasy.
There are some things wrong with your code. The following will collect the indexes of every first duplicate:
def firstDuplicate(a):
num = [] # list to collect indexes of first dupes
for i in range(len(a)-1): # second to last is enough here
for j in range(i+1, len(a)):
if a[i]==a[j]: # while-loop made little sense
num.append(j) # grow list and do not override it
break # stop inner loop after first duplicate
print(num)
There are of course more performant algorithms to achieve this that are not quadratic.
Ok so I have an array in python. This array holds indices to another array. I removed the indices I wanted to keep from this array.
stations = [1,2,3]
Let's call x the main array. It has 5 columns and I removed the 1st and 5th and put the rest in the array called stations.
I want to be able to create an if statement where the values from stations are excluded. So I'm just trying to find the number of instances (days) where the indices in the stations array are 0 and the other indices (0 and 4) are not 0.
How do I go about doing that? I have this so far, but it doesn't seem to be correct.
for j in range(len(x)):
if x[j,0] != 0 and x[j,4] != 0 and numpy.where(x[j,stations[0]:stations[len(stations)-1]]) == 0:
days += 1
return days
I don't think your problem statement is very clear, but if you want the x cols such that you exclude the indices contained in stations then do this.
excluded_station_x = [col for i, col in enumerate(x) if i not in stations]
This is a list comprehension, its a way for building a new list via transversing an iterable. Its the same as writing
excluded_station_x = []
for i, col in enumerate(x):
if i not in stations:
excluded_station_x.append(col)
enumerate() yields both the value and index of each element as we iterate through the list.
As requested, I will do it without enumerate.
You could also just del each of the bad indices, although I dislike this because it mutates the original list.
for i in stations:
del x[i]
I am new to Python programming and I am trying to write code to check if a DFA( Deterministic Finite Automata) has empty language or not.
I am using 2-d array to store state of the DFA.
On executing the code I keep getting list index out of range. How can I fix this?
Below is the code
top=-1
count=0
n=int(input("\nEnter the no of states"))
mat=[[]]
b=[]
print("\nEnter the transition table")
for i in range(0,n):
for j in range(0,n):
mat.append(input())
finalState=input("\nEnter the final state:")
startState=input("\nEnter the start state:")
for i in range(0,n):
for j in range(0,n):
if mat[i][j]:
b[++top]=j
for k in range(top):
if b[k]==finalState:
count+=1
if count>0:
print("\nLanguage is not empty")
else:
print("\nLanguage is empty")
when you make a 2x2 table, you want mat to be [[1,2],[3,4]], but you're getting [[],1,2,3,4] right now.
Instead, try:
mat = []
for i in range(n):
row = []
for j in range(n):
row.append(input())
mat.append(row)
Also, Python does not have a "++" operator, so b[++top]=j is the same as b[top] = j. If you want to increment top, you have to do that on its own line before you use it to index the list.
On top of that, b has zero elements, so indexing it in any way will cause a crash. If you're trying to increase the size of b by adding new items to it, use append. Then you don't need a top variable at all.
b.append(j)
Even though I am getting valid Prints but still I am getting List Index out of range. The list where I am getting "Out of Range" error is "lstSHADOW_LOG_TABLE"
if((int(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]))) > 1):
print("Length={0} and Value={1}".format(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]), lstSHADOW_LOG_TABLE[index_shadow_log][1]))
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:][1]):
if(lstSHADOW_LOG_TABLE[index_shadow_log][1] == lstCAN_LOG_TABLE[index_can_log][1]):
#Some Calculation
else:
break
OUTPUT:
Length=3 and Value=340
Traceback (most recent call last):
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:][1]):
IndexError: list index out of range
EDITED FROM HERE (CODE MODIFIED TO INCORPORATE SUGGESTION):
The List "lstSHADOW_LOG_TABLE" is a List of Lists. Now let us say I want the comparison to start fresh from index "index_shadow_log" (SubList "index_shadow_log" onwards)
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:]):
Thanks for your answers, I now understood that the meaning of this for loop would be start iteration for List "lstSHADOW_LOG_TABLE" starting from index "index_shadow_log:"
This is my extracted code:
for index in range(len(lstCAN_LOG_TABLE)):
for l_index in range(len(lstSHADOW_LOG_TABLE)):
#print(lstSHADOW_LOG_TABLE[l_index][0])
#print(lstSHADOW_LOG_TABLE[l_index][1])
if(lstSHADOW_LOG_TABLE[l_index][1] == lstCAN_LOG_TABLE[index][1]): #Consider for comparison only CAN IDs
print("matching")
#print(lstCAN_LOG_TABLE[index][0])
#print(lstSHADOW_LOG_TABLE[l_index][0])
index_can_log = index #Position where CAN Log is to be compared
index_shadow_log = l_index #Position from where CAN Shadow Log is to be considered
print("Length={0} and Value={1}".format(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]), lstSHADOW_LOG_TABLE[index_shadow_log][1]))
bMatchFound = 1
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:]): #Start comparison
if(lstSHADOW_LOG_TABLE[index_shadow_log][1] == lstCAN_LOG_TABLE[index_can_log][1]): #Compare individual element
dump_file.write("\n")
dump_file.write("SHADOW: " + str(lstSHADOW_LOG_TABLE[index_shadow_log])) #Dump if equal
writer_two.writerow(lstSHADOW_LOG_TABLE[index_shadow_log][0]) #Update CSV File
dump_file.write("\n")
dump_file.write("CAN: " + str(lstCAN_LOG_TABLE[index_can_log])) #Dump if equal
writer_one.writerow(lstCAN_LOG_TABLE[index_can_log][0]) #Update CSV File
if(index_can_log < (input_file_one_row_count - 1)): #Update CAN LOG Index
index_can_log = index_can_log + 1
if(index_can_log >= (input_file_one_row_count - 1)):
break
else:
bMatchFound = 0
break
if(bMatchFound == 0):
break
dump_file.close()
I need to get rid of parenthesis (Sorry coming from C/C++ background we love braces and parenthesis :-P) and make the code a lot cleaner. Thanks all for your suggestions
Compare:
lstSHADOW_LOG_TABLE[index_shadow_log][1]
with
lstSHADOW_LOG_TABLE[index_shadow_log:][1]
The first indexes lstSHADOW_LOG_TABLE, then indexes whatever that returned. The second slices lstSHADOW_LOG_TABLE; this returns a new list. You then indexed that sliced list. If that sliced list has only 1 element, then indexing the second is going to fail.
You really need to cut back on the parentheses here, and simplify the code somewhat. Use a temporary variable to store the indexed element:
value = lstSHADOW_LOG_TABLE[index_shadow_log][1]
if value:
print("Length={0} and Value={1}".format(len(value), value))
for l_inner_element in value:
if value == lstCAN_LOG_TABLE[index_can_log][1]:
#Some Calculation
else:
break