如何为给定方程优化以下python代码?

时间:2019-11-29 00:29:33

标签: python-3.x optimization multidimensional-array numpy-ndarray computation

for the following equation,python code needs to be optimized. By considering random initialization of variables

我编写了以下python代码,但是执行时间太长,是否可以用最少的for循环编写代码?
import numpy as np

N=10
K=3
D=4
M_ikl = np.zeros((N,K,D))
one_minu_theta = np.random.randint(5, size=(N,D))+0.5
F = np.random.randint(2, size=(K,D))+0.5
sigma = np.random.randint(2, size=(K,D))+0.5
dat = np.random.randint(2, size=(N,D))+0.5
tau = np.random.randint(2, size=(K,D))+0.5
exp_gamma = np.random.randint(2, size=(K))+0.5
exp_gamma_minus = np.random.randint(2, size=(K))+0.5    

M_ikl = np.zeros((N,K,D))
for i in range(N):
    for k in range(K):
        for l in range(D):
            M_ikl[i][k][l] = np.exp(one_minu_theta[i][l]*(F[k][l]+(sigma[k][l]-1)*np.log(dat[i][l])-(sigma[k][l]+tau[k][l])*np.log(1+dat[i][l])) + exp_gamma[k]+  np.sum(exp_gamma_minus[:-1]))    

1 个答案:

答案 0 :(得分:0)

您可能正在执行大量重新计算。

M_ikl[i][k][l] = np.exp(
    one_minu_theta[i][l] * (
       F[k][l] + 
       (sigma[k][l]-1) * np.log(dat[i][l]) - 
       (sigma[k][l]+tau[k][l]) * np.log(1+dat[i][l])
     ) + 
     exp_gamma[k] + 
     np.sum(exp_gamma_minus[:-1])
)

您要避免在算法的核心中执行日志和求和

log_dat = np.log(dat)
log_dat_p1 = np.log(1+dat)
sum_gamma = np.sum(exp_gamma_minus[:-1])

for ... :
    M_ikl[i][k][l] = np.exp(
        one_minu_theta[i][l] * (
           F[k][l] + 
           (sigma[k][l]-1) * log_dat[i][l] - 
           (sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
         ) + 
         exp_gamma[k] + 
         sum_gamma
    )

接下来,我将考虑在循环之外最后进行指数运算。

for ... :
    lnM_ikl[i][k][l] = 
        one_minus_theta[i][l] * (
           F[k][l] + 
           (sigma[k][l]-1) * log_dat[i][l] - 
           (sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
         ) + 
         exp_gamma[k] + 
         sum_gamma

M = np.exp(lnM_ikl)

(我认为您的sum_gamma项是错误的,因为它取决于方程式中的k,但不取决于您的实现中的k-我将继续假设它没问题)

现在您可以尝试将其拆分以使用numpys分布和张量积等。 但是我认为创建一个小的numba函数已经很简单了,应该可以很快得到结果。

@numba
def calc_log_M(one_minus_theta, F, sigma, log_dat, logdat_p1, exp_gamma, sum_gamma):
   lnM = np.zeros(...)
   for ... :
      lnM[i][k][l] = 
        one_minus_theta[i][l] * (
           F[k][l] + 
           (sigma[k][l]-1) * log_dat[i][l] - 
           (sigma[k][l]+tau[k][l]) * logdat_p1[i][l]
         ) + 
         exp_gamma[k] + 
         sum_gamma
   return lnM

log_dat = np.log(dat)
log_dat_p1 = np.log(1+dat)
sum_gamma = np.sum(exp_gamma_minus[:-1])

M = np.exp(calc_log_M(one_minus_theta, F, sigma, log_dat, logdat_p1, exp_gamma, sum_gamma))

您可能需要调整numba参数以获得最佳性能。