微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

优化嵌套 for 循环所花费的时间

如何解决优化嵌套 for 循环所花费的时间

我有一本字典。假设“数据”和一个 numpy 数组。让我们说'统计'。 我想检查是否:-

numpy 数组的第一列和第二列存在于我的字典字典中的 2 个键的范围内,或者如果这 2 个键存在于我的 numpy 数组中的列范围内。

提供我的代码以供参考 主要问题是这需要花费大量时间,如果您能帮助我们使其运行得更快,我们将不胜感激。

任何帮助将不胜感激,谢谢

final = []
for x,y,w,h,area in stats[:]:
    valid = True
    if any([(x in range(s["hpos_start"]-2,s["hpos_end"] + 2) and y in range(s["vpos_start"]-2,s["vpos_end"] + 2)) or ((int(s['hpos_start']) in range(x,x+w) and int(s['vpos_start']) in range(y,y+h))) for _,s in data.items()]):
        valid = False
    if valid:
        final.append([x,h])

统计样本=

         [[    246       1102    1678   2214  172182],[     678       1005    1688   2214  3528850],[     1031      241     17     23    331]]

数据样本=

{'0': {
  'hpos_start': 244,'hpos_end': 296,'vpos_start': 1099,'vpos_end': 3898,},'1': {
  'hpos_start': 679,'hpos_end': 952,'vpos_start': 231,'vpos_end': 281
  },'2': {'hpos_start': 1077,'hpos_end': 1174,'vpos_end': 281
  }}

stats 大约是大小 (352,5) 数据大小约为 212

也可以超过以上

解决方法

我的建议是将统计信息和数据都转换为 numpy 数组,然后找出一种方法来实现您的特定过滤而无需使用显式 {{1 }}-循环。这就是 numpy 的全部优势!然后你会使用特殊的索引方法来生成你的 for 数组,而不是一个一个地构建它。附加到列表可能有点慢...

对于小而易于实现的加速:当您在代码中使用 finalany 时,您应该避免将 all 传递给它,因为您可以将它传递给生成器表达代替。如果您只是从 list 内部删除方括号,您应该会看到一点加速,因为您将避免总是构建完整的中间列表! any(和 any)的一个很酷的事情是,在处理迭代器时,它们有所谓的短路:一旦 all 找到一个 any ,它知道它可以停止查看其余项目,因为答案将是 True。同样,一旦 true 找到 all 的项目,它就会停止查看其余项目并返回 False

但实际上,将您的输入转换为 numpy 数组(或者可能是一个 numpy 数组和一个 Pandas 数据帧),然后尝试找出避免 for 循环的方法。

,

为了测试和计时您的代码,我在 for 循环中运行了 100000 次。您的代码运行时间为 1.406 秒。我提出以下代码:用极限测试替换“范围内”测试,抑制 int(..) 强制转换,它在我的电脑上运行时间为 0.609 秒。在你的电脑上试一试,看看你能获得什么速度:

import time
start = time.process_time()

for i in range(100000) :

    ## 100000x 0.609
    final = []
    for x,y,h,w,area in stats:
        if    any([
                    ((
                        (s["hpos_start"]-2) <= x and x <= (s["hpos_end"] + 2)
                    and
                        ((s["vpos_start"]-2)<=y and y <=( s["vpos_end"] + 2))
                    ))
                    or ((
                           (x<= s['hpos_start'] <= (x+w))
                           and
                           (y<= s['vpos_start'] <=(y+h))
                       ))
                    for s in data.values()
              ]):
            pass
        else:
            final.append([x,h])
    
print(time.process_time() - start)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。