lmw0320 2019-05-23 15:14 采纳率: 75%
浏览 341
已采纳

如何提高这段代码的运行速度?

手头有一些数据,需要统计某几个指定字段,与标准字段数值的比较。统计超过标准值的字段个数。
大致数据格式如下:
图片说明

我的代码如下:(个人觉得有更快速的方法来解决)

def cal(x):
    cnt = 0
    for i in data.columns[:5]:
        if x[i] > x['ZB']:
            cnt +=1
    return cnt
data['XX'] = data.apply(cal,axis=1)

结果1000行的数据,运行起来貌似偏慢了点,要0.2秒左右。。
想请教下高手,有没办法可以提高效率?
如用np.where等方法来处理。。(主要考虑到以后如果有100W+的数据,不是得跑很久。。)

  • 写回答

3条回答 默认 最新

  • D720CJM 2019-05-29 19:56
    关注

    怎么弄都是那样了,尽量少转换,少生成新变量呗……
    不过,何不开多线程呢?
    把需要处理的项目分成一行行来处理,多行就多个线程同时统计,最后再把统计的结果相加。

    from concurrent.futures import ThreadPoolExecutor
    pool = ThreadPoolExecutor(max_workers=15) # 最大线程数设置
    
    def cal(x):
        cnt = 0
        for i in data.columns[:5]:
            if x[i] > x['ZB']:
                cnt +=1
        return cnt
    data['XX'] = data.apply(cal,axis=1)
    
    parms = [1,2,3……] # 参数列表
    rets = list()
    gen = pool.map(cal, parms) **# 加入线程池,返回gen是一个iterators
    rets.extend(list(gen)) # 这样rets就是每一行的统计结果cnt了
    cnt = 0
    for i in rets: 
        cnt += i
    pool.shutdown() # 关闭线程池(确保你不要再用线程的地方)
    # 这里你自己想办法生成参数列表parms,比如说range(min_row, max_row + 1),那么就是parms = [i for i in range(min_row, max_row + 1)]
    # 把parms作为参数传递进cal函数,那么cal(1)就是第一行,cal(2)就是第二行了……以此类推。用多线程,少量任务时不见得更快,但很多数据还是好使的
    # PS:map()接收一个函数 f 和一个list(或多个 list,但list个数与f函数的参数个数必须相等),并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 iterators 并返回。
    
    

    不大懂你的data['XX'] = data.apply(cal,axis=1)是什么……

    要不就还是你原来的代码,但是加上jit,变成这样试试

    from numba import jit
    
    @jit
    def cal(x):
        cnt = 0
        for i in data.columns[:5]:
            if x[i] > x['ZB']:
                cnt +=1
        return cnt
    data['XX'] = data.apply(cal,axis=1)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?