【问题标题】:I have some code that take under 2 seconds to run 100 iterations, under 8 seconds to run 1000, and over 11 minutes to run 10,000我有一些代码在 2 秒内运行 100 次迭代,在 8 秒内运行 1000 次,在 11 分钟内运行 10,000 次
【发布时间】:2021-07-19 03:50:18
【问题描述】:

我是一个业余程序员,这只是我为自己设定的一个小项目。我知道我很可能在这段代码中有一些东西效率低到对小循环无关紧要,但是当我扩大它时会变得复杂。任何建议将不胜感激。

def RndSelection(ProjMatrix):
    
    
    percentiles = [0,10,20,25,30,40,50,60,70,75,80,90,99]
    results = []
    
    
    for row in ProjMatrix.itertuples():
        
        x = npr.randint(1,100)
        
        for p in range(3,16):
            
            if  p < 15:
                a = percentiles[p-3]
                b = percentiles[p-2]
                
                if x in range (a,b):
                
                                   
                    factor = (b-x)/(b-a)
                    r = round((row[p]*factor)+((row[p+1])*(1-factor)),2)
                    break
            else:
                r = row[p]

        results.append(r)
        
    thisrun = pd.DataFrame(results)
    
        
    return(thisrun)
                    

def main():

    ts = datetime.datetime.now()
    print ('Run Started: ', ts)    

    Matrix = SetMatrix()
    Outcome = Matrix['player_id']

    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = [executor.submit(RndSelection,Matrix) for _ in range(10000)]

        for f in concurrent.futures.as_completed(results):
            thisrun = f.result()
            Outcome = pd.concat([Outcome,thisrun],axis=1)




    print(Outcome)

    ts = datetime.datetime.now()
    print('Run Completed: ', ts)


if __name__ == '__main__':
    main()

【问题讨论】:

  • 不是minimal reproducible example。缩进错误。缺少功能。
  • 对不起,我尝试了几分钟让它在代码示例粘贴中正确缩进。缺少的功能是读取 csv 数据并放入表格中。由于它依赖于源数据,因此我无法在此处轻松复制,并且仅在循环之外被调用一次,我认为它不相关。如果我弄错了,我可以编写一个快速的随机数生成器来模拟数据。
  • 仍然缺少像SetMatrix这样的函数。问题来自导致二次运行时的 concat。见this answer

标签: python-3.x optimization multiprocessing


【解决方案1】:

因此,正如 Jérôme 指出的那样,答案是 concat 的迭代。

将输出移动到列表列表,然后只连接一次,将 10,000 次交互的运行时间缩短到 8 秒,将 100,000 次迭代的运行时间缩短到 2 分 34 秒。

def RndSelection(ProjMatrix):
    
    
    percentiles = [0,10,20,25,30,40,50,60,70,75,80,90,99]
    results = []
    r = ""
    
    for row in ProjMatrix.itertuples():
        
        x = npr.randint(1,100)
        
        
        for p in range(3,16):
            
            if  p < 15:
                a = percentiles[p-3]
                b = percentiles[p-2]
                
                if x in range (a,b):
                
                                   
                    factor = (b-x)/(b-a)
                    r = round((row[p]*factor)+((row[p+1])*(1-factor)),2)
                    break
            else:
                r = row[p]

        results.append(r)
        

    
        
    return results
                    




def main():

    ts = datetime.datetime.now()
    print ('Run Started: ', ts)    

    Matrix = SetMatrix()
    runs = 100000
    s = 0
    Outcome = pd.DataFrame(Matrix['player_id'])
    
    thisrun = np.empty((runs,0)).tolist()

    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = [executor.submit(RndSelection,Matrix) for _ in range(runs)]

        for f in concurrent.futures.as_completed(results):

            thisrun[s]=f.result()
            s += 1

    allruns = pd.DataFrame(thisrun).transpose()
    Outcome = pd.concat([Outcome,allruns],axis=1)




    ts = datetime.datetime.now()
    print('Run Completed: ', ts)

if __name__ == '__main__':
    main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 2018-12-19
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多