Создать массив с биномиальными значениями (наиболее эффективный по времени) на основе условий - PullRequest
0 голосов
/ 21 декабря 2018

В настоящее время я работаю над проектом, который включает создание массива с 10 биномиальными значениями 0 и 1 и заданным коэффициентом успешности (= ci_rate [i] / 1'000).

В связи с тем, что для каждого из 10 лет частота разная, я запускаю цикл 10 раз, каждый раз создавая 20 000 биномиальных значений (для 20 000 сценариев).

Показатель успеха для биномиальных значений очень мал, но в последующие годы это поглощающее состояние.Упрощенный только для 10 сценариев и 10 лет, я хотел бы вывести следующее:

[1,0,0,0,0,0,0,0,0,0]
[1,0,0,0,0,0,0,1,0,0]
[1,0,0,1,0,0,0,1,0,0]
[1,0,0,1,0,0,0,1,0,0]
[1,0,0,1,0,0,0,1,0,0]
[1,0,0,1,0,0,0,1,0,0]
[1,0,0,1,0,1,0,1,0,0]
[1,0,0,1,0,1,0,1,0,0]
[1,0,0,1,0,1,0,1,0,0]
[1,0,0,1,0,1,0,1,0,0]

В настоящее время я решаю проблему следующим образом:

for j in range(20000):
    tem = np.zeros(len(ci_rate))
    for i in range(len(ci_rate)):
        if i == 0:
            tem[0] = (np.random.binomial(1, p = ci_rate[i] / 1000))
        else:
            tem[i]= int(np.where(tem[i-1]==1, 1, np.random.binomial(1, p = ci_rate[i] / 1000)))

    ci_sim.append(tem)

Кто-нибудь достаточно изобретателен, чтобы решитьэто более эффективное время?

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Моя попытка будет:

import numpy as np
ci_rate = np.random.normal(size=20)
ci_rate = (ci_rate - min(ci_rate)) /(max(ci_rate) - min(ci_rate)) - 0.7
ci_rate[ci_rate < 0] = 0
r = []
for i in range(100):
    t = np.random.binomial(1, ci_rate)
    r += [t.tolist()]
    ci_rate = [1 if j == 1 else i for i, j in zip(ci_rate, t)]


#output 

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0],
0 голосов
/ 21 декабря 2018

Это решение сначала игнорирует правило персистентности и впоследствии применяет его, используя maximum.accumulate.

ci_rate = np.random.uniform(0, 0.1, 10)
res = np.maximum.accumulate(np.random.random((20000, ci_rate.size))<ci_rate, axis=1).view(np.int8)
res[:20]
# 
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
#        [0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int8)
0 голосов
/ 21 декабря 2018

Я предлагаю геометрическое распределение , так как похоже, что вы пытаетесь увидеть количество испытаний для первого успеха.

Я сравниваю полезность использования геоментрического распределения с точки зрения времени вычислений

EDIT:
%%timeit
ci_rate = np.random.uniform(0, 0.1, nb_years)
successful_trail = np.random.geometric(p=ci_rate)

ci_sim=np.zeros((nb_scenarios,nb_years))
for i in range(nb_years):
    ci_sim[i,successful_trail[i]:]=1

## 10000 loops, best of 3: 41.4 µs per loop

%%timeit
ci_rate = np.random.uniform(0, 0.1, nb_years)
res = np.maximum.accumulate(np.random.random((nb_scenarios, ci_rate.size))<ci_rate, axis=1).view(np.int8)

## 100 loops, best of 3: 2.97 ms per loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...