2017-10-10 123 views
0

我正在編寫癌細胞羣體增長的模擬,並且我使用numpy.random函數來模擬獲取或失去突變的細胞。我通過分析確定代碼中的瓶頸(大約70%的運行時間)是包含numpy.random函數的前幾行。這裏變量num_steps是一個大數,大約一百萬:提高numpy.random函數的速度

def simulate(mu, gamma, beta, num_steps, threshold): 
    mutation_num = 0 # the index of the mutation (we assume each mutation only occurs once) 
    population = {() : 1} # represents population: tuple of mutations and number of cells with those mutations 
    for epoch in range(num_steps): 
     next_population = {} 
     for mutations, size in population.items():  
      born = np.random.binomial(size, birth_rate) 
      if np.random.binomial(born, gamma): 
       return True 
      mut_loss = 0 # initializing in case variable is not created 
      if mutations: 
       mut_gain, mut_loss, mut_same = np.random.multinomial(born, [mu, beta, 1-mu-beta]) 
      else: 
       mut_gain, mut_same = np.random.multinomial(born, [mu, 1-mu]) 
..... 

有沒有一種方法,使np.random.binomialnp.random.multinomial功能運行得更快?我嘗試過使用Cython,但這沒有幫助。

+0

你可能想要用'xrange'替代'range',這是一個懶惰的等價物,並且看看這有多幫助;或者用一段時間替換它並手動增加值(這實際上是相同的優化)。 –

+0

@BurhanKhalid'range'與'xrange'的觀察結果只對Python 2有效。你確定OP沒有使用Python 3嗎? –

+0

我正在使用python 3.正如我已經提到的那樣,profiler表明瓶頸是在numpy隨機函數的周圍。 – Alex

回答

2

爲了說明我的意見:

In [81]: timeit np.random.binomial(1,1,1000) 
46.4 µs ± 1.53 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
In [82]: %%timeit 
    ...: for _ in range(1000): 
    ...:  np.random.binomial(1,1) 
    ...: 
4.77 ms ± 186 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

如果可能產生一個電話,而不是一次一個隨機值。

+0

謝謝,這幫了很大的忙! – Alex