I have this while loop, and I was wondering if their is a more pythonic way to write it:
k = 1
while np.sum(s[0:k]) / s_sum < retained_variance:
k += 1
s
is a numpy vector. Thanks!
The best way to make the condition change from True to False is to use a variable as part of the Boolean expression. We can then change the variable inside the while loop.
You need to initialize previous guess before while loop Otherwise it will be initialized again and again. You have to set the value of previous guess to x the computer generator and when you move on after loop you have to update the previous guess to next simply like this: Add before while { previous_guess = x }
The "while true" loop in python runs without any conditions until the break statement executes inside the loop. To run a statement if a python while loop fails, the programmer can implement a python "while" with else loop. Python does not support the "do while" loop.
You are only printing the output of test() , not updating the variable a so this will always be 0 at each iteration of your loop. when you call test(a) you just print the result, a is never updated - i.e. it stays 0, you just throw away the value returned.
I'd say it's pretty pythonic: explicit is better than implicit.
Probably not the most efficient solution, but fast if most of the array needs to be searched:
import numpy as np
ss = np.cumsum(s) # array with cumulative sum
k = ss.searchsorted(retained_variance*s_sum) # exploit that ss is monotonically increasing
EDIT: Simon pointed out that
k = np.cumsum(s).searchsorted(retained_variance*s_sum) + 1
is the value which corresponds to the question.
The last line of the following code will find the value of k
in one line:
import numpy as np
import math
s = np.array([1,2,3,4,5,6,7,8,9])
s_sum = 1
retained_variance = 4.3
k = 1
while np.sum(s[0:k]) / s_sum < retained_variance:
k += 1
print (k)
print (np.ceil(np.interp(retained_variance,s.cumsum()/s_sum,range(1,len(s)+1))))
this is more like Haskell than python:
>>> from itertools import count, dropwhile
>>> pred = lambda k: np.sum(s[:k]) / s_sum < retained_variance
>>> head = next # just to look more like haskell
>>> head(dropwhile(pred, count()))
edit: this will be more efficient:
>>> from itertools import dropwhile, accumulate
>>> pred = lambda x: x[1] / s_sum < retained_variance
>>> head = next
>>> head(dropwhile(pred, enumerate(accumulate(s), start=1)))[0]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With