【问题标题】:Fastest way to iterate 2 arrays and perform operations迭代 2 个数组并执行操作的最快方法
【发布时间】:2021-10-18 15:18:26
【问题描述】:

我有一个函数,它将 2 个零数组和一个数组作为输入,每个数组约 8000 个元素。我的函数 eps 计算这些数组的统计数据并返回输出。只需检查 0 并注意在数组中找到 0 的索引,操作很简单。我尽力优化速度,但我能得到的最好结果是使用 timeit 库 4.5 ~5 秒(对于 18k 数组对)。时间很重要,因为我需要在数十亿个数组对上运行这个函数。

    #e.g. inputs
    #ts_1 = [0,1,1,0,0,1,1,0,......]
    #ts_2 = [1,1,1,1,1,1,1,0,......]
    # tau = any integer or float
    
def eps(ts_1, ts_2, tau):  
    
    n1 = 0
    n2 = 0
    Q_tau = 0
    q_tau = 0

    event_index1 = [index for index, item in enumerate(ts_1) if item == 0]
    n1 = ts_1.count(0)
    event_index2 = [index for index, item in enumerate(ts_2) if item == 0]
    n2 = ts_2.count(0)


    # tried numpy based on @Ram comment below, no improvement
    event_index1, = np.where(np.array(ts_1) == 0)
    n1 = event_index1.shape[0]
    
    event_index2, = np.where(np.array(ts_2) == 0)
    n2 = event_index2.shape[0]
    # tried numpy based on @Ram comment below, no improvement   

    if (n1 == 0 or n2 == 0):
        Q_tau = 0
    else:
        c_ij = 0  
        matching_idx = set(event_index1).intersection(event_index2)
        c_ij = c_ij + (0.5 *len(matching_idx) )
        
        for x,y in product(event_index1,event_index2):
            if x-y > 0 and (x-y)<= tau:
                c_ij = c_ij +1  
        
        c_ji = 0            
        matching_idx_2 = set(event_index2).intersection(event_index1)         
        c_ji = c_ji + (0.5 *len(matching_idx_2) )
        
        for x,y in product(event_index2,event_index1):
            if x-y > 0 and (x-y)<= tau:
                c_ji = c_ji +1                       
                  
        Q_tau = (c_ij+c_ji)/math.sqrt( n1 * n2 )
        q_tau = (c_ij - c_ji)/math.sqrt( n1 * n2 )
    
    return Q_tau, q_tau

【问题讨论】:

  • 我认为如果您想要更快的方式,最好使用numpy。请通过这个答案 - stackoverflow.com/a/18079151/2773206
  • 首先你可以用n1 = len(event_index1)替换n1 = ts_1.count(0)
  • 二、matching_idx_2 = set(event_index2).intersection(event_index1)的目的是什么?同matching_idx
  • @Ram 感谢您的建议,我使用了 numpy 数组但没有任何改进,而是时间增加到 5.8 秒
  • @smac89 谢谢我把它贴在那里codereview.stackexchange.com/questions/266108/…

标签: python list dictionary timeit


【解决方案1】:

根据我之前的 cmets,考虑到在产品中排列两个列表会给您提供刚刚反转的相同元组,您可以将代码简化为:

def eps(ts_1, ts_2, tau):  
    Q_tau = 0
    q_tau = 0

    event_index1 = [index for index, item in enumerate(ts_1) if item == 0]
    n1 = len(event_index1)
    event_index2 = [index for index, item in enumerate(ts_2) if item == 0]
    n2 = len(event_index2)
    
    if (n1 != 0 and n2 != 0):
        matching_idx = set(event_index1).intersection(event_index2)
        c_ij = c_ji = 0.5 *len(matching_idx)
        
        for x,y in product(event_index1,event_index2):
            if x-y > 0 and (x-y)<= tau:
                c_ij += 1
            elif y-x > 0 and (y-x) <= tau:
                c_ji += 1                     
                  
        Q_tau = (c_ij+c_ji)/math.sqrt( n1 * n2 )
        q_tau = (c_ij - c_ji)/math.sqrt( n1 * n2 )
    
    return Q_tau, q_tau

【讨论】:

  • 感谢您的清理,但大约 18k 阵列对的时间几乎相同,为 4.7 ~ 4.9 秒。这相当于每个阵列对约 0.0002 秒。我不确定我是否可以改进这一点。因为这是我需要执行十亿次计算的瓶颈
  • 你能分享一个ts1和ts2的样本吗?以及 tau 的典型值。您可以使用详细信息更新您的问题。
  • 我添加了它完成:)
猜你喜欢
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 2017-03-28
相关资源
最近更新 更多