Reputation: 125
I am tasked with running a for-loop which initially finds the value of funds in a mans investment account from his 41-65th birthday. Here is the code below.
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
np.exp(np.random.normal(mu, sigma,))
u = .076 ###set variables
bi = 50000 ###set variables
empty = [] ###empty list
for i in range(25): ###range for birthdays 40-65
bi = ((bi) * (np.exp(np.random.normal(mu, sigma))))
empty.append(bi)
print(empty)
len(empty) ##making sure my lists match up
roundedempty = [ '%.2f' % elem for elem in empty ]
age = [41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65]
len(age) ##making sure my lists match up
investing = pd.DataFrame({"Balance":roundedempty, "Age":age})
investing.set_index('Age', inplace=True)
investing
When I print this out it give me this:
Age Balance
41 53948.13
.........
65 334294.72
Now I am tasked with simulating this 100,000 times, but I am not sure how to nest another loop within that first set of code.
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
bi = 50000
lognormvals = np.zeros(100000)
for i in range(100000):
lognormvals[i] = ((bi) * (np.exp(np.random.normal(mu, sigma,))))
print(lognormvals)
np.mean(lognormvals)
This is what I want, but it is only doing it for his 41st birthday. I am tasked with trying to find the means of each birthday from his 41-65th. How can I nest this loop within the first loop to solve this?
My Shot at solving:
def InvestmentSim():
mu = 0.076 ###Mean
sigma = 0.167 ###Standard deviation
np.exp(np.random.normal(mu, sigma,))
u = .076 ###set variables
bi = 50000 ###set variables
empty = [] ###empty list
for i in range(25): ###range for birthdays 40-65
bi = ((bi) * (np.exp(np.random.normal(mu, sigma))))
empty.append(bi)
roundedempty = [ '%.2f' % elem for elem in empty ]
age = [41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65]
len(age) ##making sure my lists match up
investing = pd.DataFrame({"Balance":roundedempty, "Age":age})
investing.set_index('Age', inplace=True)
a = investing.iloc[24]['Balance']
return a
def AverageSim(iterations):
results = []
for n in range (0, iterations):
a = InvestmentSim()
results.append(a)
print(results)
return myresult
myresult = AverageSim(1)
myresults = np.array(myresult) # Turn the list of values into an array
mean = np.mean(myresults)
median = np.median(myresults)
print(mean, median)
Instead of doing all the balance for each year instead I just singled out the balance on his 65th birthday and set it equal to (a). Is this how my code should work? Doesn't seem to be running
Upvotes: 1
Views: 126
Reputation: 166
If you just want to repeat the first snippet n times, then I'd suggest wrappning your code for the simulation, up in a function which you can call repeatedly in a for loop. The function should return your expected values, and the for loop should collect the results. After the loop is finished you can do further calculations with the loop such as mean.
# Your simulation as a callable function
def InvestmentSim():
# your first code
return investing
def AverageSims(iterations):
# Initialise an empty list to collect the results
results = []
for n in range (0, iterations):
investing = InvestmentSim()
results.append(investing)
# Adds investing to the end of the list
# Returns a list of all the dataframes which you can use for future
# calculations.
# Or do the desired calculations here and return only those results.
return results
myresult = AverageSims(100000)
Note that with 100,000 iterations you will get a very long list of fairly bulky dataframes. So instead you may want to do some calculations in place or pull out relevant results from each iteration and discard the rest. For example you could just save the start and end balances from each sim and append those to lists and return those.
I'd give an example but I don't use pandas so I don't want to guess at the syntax. The basic principle is the same though: Initialise some blank lists and append the results in the for loop.
Calculations will probably be simpler to set up if you turn the finished list(s) into numpy arrays using np.array(somelist)
Your code isn't running because you're calling the AverageSims function inside the AverageSims function, so you never actually get to that call. You need to move that call outside so it's executed when you run your script. The simplest way is to write the call the same way I did above, outside any function and without indentation.
Also, if your AverageSims() function doesn't have the return mysresults line, it will return None instead. That's not a problem unless you want to use results later on. If you don't want to keep the results and are happy with printing them out as you do now, you can also call the function without equating it to a variable:
def InvestmentSim():
# your first code
return investing
def AverageSims(iterations):
# Repeatedly do the simulation, collect results
# Returning the results, if you don't need them you can omit this:
return myresult
# Now call the AverageSims function, otherwise it will never be executed. Note: No indent.
myresults = AverageSims(100000) # If you're returning the results
# OR:
AverageSims(100000) # If you don't return the results
myresult = np.array(myresult) # Turn the list of values into an array
mean = np.mean(myresult)
median = np.median(myresult)
print(mean, median)
Upvotes: 2
Reputation: 5185
You can just put a loop inside another loop:
for x in range(10):
for y in range(5):
print(x,y)
I your case it would also be advisable to put the inner loop into a function, and run that function in the outer loop. Like this:
def calculate(*args):
# do your calculations here that include a loop
return result
for x in range(100000):
calculate()
Upvotes: 0