Как оптимизировать вложенные циклы?
Имеется список случайно выпавших чисел (0 или 1) длиною в 10000 элементов. В записи это выглядит так: X = np.random.randint(0, 2, 10000) (задача с подбрасыванием монеты).
Нужно рассчитать вероятность получения 0 или 1 для каждого количества экспериментов, в данном случае - подбрасываний. Например, при количестве 10000 подбрасываний получаем 4994 результата '1'. Это получилось рассчитать с помощью:
y = {i:list(X[0:10000]).count(i) for i in list(X[0:10000])}
На этой основе написал цикл, внутри которого оказался и этот цикл:
lst = []
for i in range(1,len(X)+1):
y = {j:list(X[0:i]).count(j) for j in list(X[0:i])}
lst.append(y[1]/i)
Понятное дело, что это не решает мою задачу.
Подскажите, как это можно оптимизировать?
Ответы (3 шт):
А sum(X)/len(X) разве не то же самое? Т.е. так:
for i in range(1,len(X)+1):
prob = sum(X[:i])/len(X[:i])
lst.append(prob)
И даже еще проще, чтоб не считать сумму десять тысяч раз:
X = np.random.randint(0, 2, 10000)
lst = []
s = 0
for i in range(len(X)):
s += X[i]
prob = s/(i+1)
lst.append(prob)
Выполняется за 0,5-1 мс.
Вы проставили тег Numpy, но совсем им не пользуютесь ;)
X = np.random.choice([0, 1], size=10000)
res = [X[:i].mean() for i in range(1, len(X))]
Замер скорости:
In [19]: %timeit res = [X[:i].mean() for i in range(1, len(X))]
86.2 ms ± 621 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Если уж пользоваться Numpy, то тогда уж так:
import numpy as np
X = np.random.randint(0, 2, 10000)
res = np.cumsum(X)/np.arange(1,10001)
То есть копим сумму выпадающих значений и делим её на число экспериментов - и всё это средствами Numpy, очень быстро.