I'm trying to have randomize number between 0-1 until the sum of those are >=1. This process iterate for nTime. Code below:
from random import random
def funct(n): #10_000
media = 0
for _ in range(n):
result = 0
count = 0
while result < 1:
x = random()
result = x
count = 1
if result >= 1:
break
media = count
return media / n
I need to optimize the above code, utilize only numpy library
, utilize numpy array, no loop python, no if python(numpy.where for example). How should I do it?
I need to optimize my code, because I'm try to reduce the time used. and my english is not the best
CodePudding user response:
I don't think you'll find any significant improvements by trying to avoid a loop here. If you for some reason need a significantly faster version of this simple system, would probably recommend simply using a faster language than Python.
CodePudding user response:
Inspired by one of the SO answers, np.random.dirichlet
or np.random.gamma
could be used, cautiously, in this regard. In one of my tests:
spec_len = 15
result = np.random.dirichlet(np.ones(spec_len), size=1)
# [[0.04798813 0.04001169 0.03344301 0.03314941 0.02594012 0.00738061
# 0.05712809 0.20175982 0.0605601 0.17495591 0.01114262 0.12018851
# 0.08900246 0.05989448 0.03745501]]
# SUM --> 0.9999999999999999
shape, scale = 0.5, 0.25
result = np.random.gamma(shape, scale, spec_len)
# [5.44188272e-03 2.81687195e-01 1.68385119e-01 1.77502131e-03
# 1.21338381e-03 1.12168743e-02 5.98830384e-02 5.69830641e-02
# 3.13285820e-02 3.92879720e-01 1.69169125e-02 3.99294001e-07
# 1.24306290e-01 1.06084121e-02 4.63536093e-02]
# SUM --> 1.208979502912514
Both will get results near 1 (np.random.gamma
is more flexible which can be used for other some magnitudes; It can be controlled by shape
and scale
).
These methods can be used in loop to ensure the sum be >= 1
; The proposed ways will be satisfying in terms of time. E.g.:
sum = 0
while sum <= 1: # sum < 1
result = np.random.dirichlet(np.ones(spec_len), size=1)
sum = np.sum(result)
# SUM --> 1.0000000000000002