How to fix list out of index? - python

Can someone help me with rearranging my code so that my list index is no longer out of range?
Update: The formula I'm trying to apply is in the image below and what is supposed to be inside of the for loops
Formula I'm Trying to Replicate
def total_balance(entries):
##lists for storage
wealth_retirement = list()
wealth = list()
temp = list()
##get values from GUI
r = float(entries[F_MEAN_RETURN].get())/100
noise = (float(entries[F_STD_DEV].get())/100) * np.random.randn(70)
w_y = float(entries[F_ANN_CONTRIB].get())
y = int(entries[F_YEARS_CONTRIB].get())
y_r = int(entries[F_YEARS_RETIRE].get())
spent = float(entries[F_ANN_SPEND].get())
## 10 runs
for i in range(10):
for years in range(70):
if years < y:
wealth[years + 1] = (wealth[years]*(1+r+noise[years])) + w_y
elif years >= y and years < 70:
if years == y:
wealth_retirement[i] = wealth[years]
wealth[years + 1] = (wealth[years]*(1+r+noise)) - y_r
temp.append(wealth)
print (mean(wealth_retirement))

If your code is written literally, meaning
wealth_retirement = list()
wealth = list()
temp = list()
is how they are defined in your actual use, not just for posting here - that is the source of your problem. You are trying to access elements in an empty list. Python does not allow you to add elements to lists by referencing an index that does not exist.
You can either make a list of zeros with the required length prior to your for loops and reset them as you go, or use .append() to add new elements.
It is also hard to tell what the error is because you have not provided the structure of the variables that are coming from your GUI.
Here you use noise as a list:
wealth[years + 1] = (wealth[years]*(1+r+noise[years])) + w_y
but here you use it as a single value:
wealth[years + 1] = (wealth[years]*(1+r+noise)) - y_r

It is because „temp”, „wealth” and „wealth_retirement” are not lists.

Related

Python: How do you add a math forumla for all elements in two lists?

I have converted three columns from an Excel document to three lists in Python.
I now wish to make a function, where I loop through all three lists and insert items from each list into a formula.
Example:
list1[1] + list2[1] / list3[1]
There are over 3000 items in all 3 lists, so having to write down a formula for every single item would take forever, so when I want the function, I want the program to automatically go from
list1[1] + list2[1] / list3[1]
to
list1[2] + list2[2] / list3[2],
then to
list1[3] + list2[3] / list3[3]
and so on.
How can I accomplish this?
Here is the (unfinished) code that I wrote so far.
df = pd.read_excel(r'C:\Users\KOM\Downloads\PO case study 1 - volume factor check NEW.xlsx')
wb = load_workbook(r'C:\Users\KOM\Downloads\PO case study 1 - volume factor check NEW.xlsx') # Work Book
ws1 = wb.get_sheet_by_name("DPPIV & SGLT2") # Work Sheet
pack_size = ws1['F'] # Column F
quantity = ws1['H'] # Column H
conversion = ws1['K'] # Column K
column_list_1 = [pack_size[x].value for x in range(len(pack_size))]
column_list_2 = [quantity[x].value for x in range(len(quantity))]
column_list_3 = [conversion[x].value for x in range(len(conversion))]
for (x, y, z) in zip(column_list_1[7:3030], column_list_2[7:3030], column_list_3[7:3030]):
NumPy implements well optimized broadcasting operations, so that's what I would use.
import numpy as np
...
column_list_1 = np.array(x.value for x in pack_size)
column_list_2 = np.array(x.value for x in quantity)
column_list_3 = np.array(x.value for x in conversion)
result = column_list_1[7:3030] + column_list_2[7:3030] / column_list_3[7:3030]
I also took the liberty to make your comprehensions more Pythonic by iterating directly over the elements. You rarely actually need to use list indices in Python.
You can use the x,y,z values you loop through and just append the answer to a new list:
answer = []
for (x, y, z) in zip(column_list_1[7:3030], column_list_2[7:3030], column_list_3[7:3030]):
answer.append(x + y / z)

item for item in numpy.ndarray

I have a numpy.ndarray Datasets which in the debug window looks like array([['13.234.... This array can have several million elements in it and I'm trying to filter it down and then randomise the order of the filtered data.
On the line RandomRows = ReducedList[RandomIndicies] I get the error only integer scalar arrays can be converted to a scalar index. From what I can see the ReducedList I'm generating is coming out in a different format [array(['13.234... and I can't figure out how to change this.
This is the code I have...
SearchRadUpper1 = 10
SearchRadUpper2 = 15
ReducedList = [Item for Item in DataSets[:] if math.sqrt((((float(Item[0]))**2) + ((float(Item[1]))**2) + ((float(Item[2]))**2))) <= SearchRadUpper1 \
or math.sqrt((((float(Item[0]))**2) + ((float(Item[1]))**2) + ((float(Item[2]))**2))) <= SearchRadUpper2]
RandomIndices = RandomGenerator.integers(
low=0, high=len(ReducedList), size=Count)
RandomRows = ReducedList[RandomIndices]
Any help would be much appreciated.
If want to filter your array, there is no need for iterating. You can instead try
SearchRadUpper1 = 10
idx = np.where((np.linalg.norm(DataSets, axis=1) <= SearchRadUpper1))
ReducedList = DataSets[idx]
Count = 100
random_idx = np.random.choice(range(len(ReducedList, Count)))
RandomRows = ReducedList[random_idx]
Also it seems like your criteria of Item <= SearchRadUpper1 or Item <= SearchRadUpper2 is not necessary as the first statement is always true if the second is true.

trying to keep the original value of a list python [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
ignore the code its working perfectly but the problem is when that i have the t list that i need it value for a procedure so what i did is i made a new empty list (aux) and put t values inside of it so the original list doesn't get changed but it still does for some reason this is the code
def listeDesTermes(k):
Un = 0
t = [1,1]
i=2
while Un < k:
Un = t[i-1] + t[i-2]
t.append(Un)
i=i+1
return(t[0:len(t)-1])
#---------------
def Maximal (t) :
Maximal = 0
for i in range(1,len(t)) :
if t[i] > t[Maximal] :
Maximal = i
return(Maximal)
#---------------
def DecompsitionK(k,aux):
s= 0
Tdecomp = []
while not k == s :
maximum = Maximal (aux)
if s + aux[maximum] <= k :
s = s+aux[maximum]
Tdecomp.append(aux[maximum])
aux[maximum] = -69
else :
aux[maximum] = -69
return(Tdecomp)
#---------------
def conctenationT(t,Tused):
for i in range(len(t)):
if t[i] in Tused :
t[i] = str(t[i])+"1"
else:
t[i] = str(t[i])+"0"
#---------------
t=listeDesTermes(50)
# problem starts here
aux = t
print(t)
Tused=(DecompsitionK(50,aux))
conctenationT(t,Tused)
print(t)
In python, variables are saved by reference and not by value. Therefore in order to create a copy of an immutable, in your particular case - a list, you must use the method of list - copy(), or the function copy from the module copy. (copy.copy, there is also copy.deepcopy which copies sub-lists as well).
You need to edit your code to:
aux = t.copy()
And it should work!

Numpy, how can i index an array, to keep items that are smaller than the previous and next 5 items following them?

I'm making a trading strategy that uses support and resistance levels. One of the ways i'm finding those is by searching for maxima's/minima's (prices that are higher/lower than the previous and next 5 prices).
I have an array of smoothed closing prices and i first tried to find them with a for loop :
def find_max_min(smoothed_prices) # smoothed_prices = np.array([1.873,...])
avg_delta = np.diff(smoothed_prices).mean()
maximas = []
minimas = []
for index in range(len(smoothed_prices)):
if index < 5 or index > len(smoothed_prices) - 6:
continue
current_value = smoothed_prices[index]
previous_points = smoothed_prices[index - 5:index]
next_points = smoothed_prices [index+1:index+6]
previous_are_higher = all(x > current_value for x in previous_points)
next_are_higher = all(x > current_value for x in next_points)
previous_are_smaller = all(x < current_value for x in previous_points)
next_are_smaller = all(x < current_value for x in next_points)
previous_delta_is_enough = abs(previous[0] - current_value) > avg_delta
next_delta_is_enough = abs(next_points[-1] - current_value) > avg_delta
delta_is_enough = previous_delta_is_enough and next_delta_is_enough
if previous_are_higher and next_are_higher and delta_is_enough:
minimas.append(current_value)
elif previous_are_higher and next_are_higher and delta_is_enough:
maximas.append(current_value)
else:
continue
return maximas, minimas
(This isn't the actual code that i used because i erased it, this may not work but is was something like that)
So this code could find the maximas and minimas but it was way too slow and i need to use the function multiple times per secs on huge arrays.
My question is : is it possible to do it with a numpy mask in a similar way as this :
smoothed_prices = s
minimas = s[all(x > s[index] for x in s[index-5:index]) and all(x > s[index] for x in s[index+1:index+6])]
maximas = ...
or do you know how i could to it in another efficient numpy way ?
I have thought of a way, it should be faster than the for loop you presented, but it uses more memory. Simply put, it creates a intermediate matrix of windows, then it just gets the max and min of each window:
def find_max_min(arr, win_pad_size=5):
windows = np.zeros((len(arr) - 2 * win_pad_size, 2 * win_pad_size + 1))
for i in range(2 * win_pad_size + 1):
windows[:, i] = arr[i:i+windows.shape[0]]
return windows.max(axis=1), windows.min(axis=1)
Edit: I found a faster way to calculate the sub-sequences (I had called windows) from Split Python sequence into subsequences. It doesn't use more memory, instead, it creates a view of the array.
def subsequences(ts, window):
shape = (ts.size - window + 1, window)
strides = ts.strides * 2
return np.lib.stride_tricks.as_strided(ts, shape=shape, strides=strides)
def find_max_min(arr, win_pad_size=5):
windows = subsequences(arr, 2 * win_pad_size + 1)
return windows.max(axis=1), windows.min(axis=1)
You can do it easily by:
from skimage.util import view_as_windows
a = smoothed_prices[4:-5]
a[a == view_as_windows(smoothed_prices, (10)).min(-1)]
Please note that since you are looking at minimas within +/- 5 of the index, they can be in indices [4:-5] of your array.

Problems with the zip function: lists that seem not iterable

I'm having some troubles trying to use four lists with the zip function.
In particular, I'm getting the following error at line 36:
TypeError: zip argument #3 must support iteration
I've already read that it happens with not iterable objects, but I'm using it on two lists! And if I try use the zip only on the first 2 lists it works perfectly: I have problems only with the last two.
Someone has ideas on how to solve that? Many thanks!
import numpy
#setting initial values
R = 330
C = 0.1
f_T = 1/(2*numpy.pi*R*C)
w_T = 2*numpy.pi*f_T
n = 10
T = 1
w = (2*numpy.pi)/T
t = numpy.linspace(-2, 2, 100)
#making the lists c_k, w_k, a_k, phi_k
c_karray = []
w_karray = []
A_karray = []
phi_karray = []
#populating the lists
for k in range(1, n, 2):
c_k = 2/(k*numpy.pi)
w_k = k*w
A_k = 1/(numpy.sqrt(1+(w_k)**2))
phi_k = numpy.arctan(-w_k)
c_karray.append(c_k)
w_karray.append(w_k)
A_karray.append(A_k)
phi_karray.append(phi_k)
#making the function w(t)
w = []
#doing the sum for each t and populate w(t)
for i in t:
w_i = ([(A_k*c_k*numpy.sin(w_k*i+phi_k)) for c_k, w_k, A_k, phi_k in zip(c_karray, w_karray, A_k, phi_k)])
w.append(sum(w_i)
Probably you mistyped the last 2 elements in zip. They should be A_karray and phi_karray, because phi_k and A_k are single values.
My result for w is:
[-0.11741034896740517,
-0.099189027720991918,
-0.073206290274556718,
...
-0.089754003567358978,
-0.10828235682188027,
-0.1174103489674052]
HTH,
Germán.
I believe you want zip(c_karray, w_karray, A_karray, phi_karray). Additionally, you should produce this once, not each iteration of the for the loop.
Furthermore, you are not really making use of numpy. Try this instead of your loops.
d = numpy.arange(1, n, 2)
c_karray = 2/(d*numpy.pi)
w_karray = d*w
A_karray = 1/(numpy.sqrt(1+(w_karray)**2))
phi_karray = numpy.arctan(-w_karray)
w = (A_karray*c_karray*numpy.sin(w_karray*t[:,None]+phi_karray)).sum(axis=-1)

Categories

Resources