如何解决优化嵌套 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
数组,而不是一个一个地构建它。附加到列表可能有点慢...
对于小而易于实现的加速:当您在代码中使用 final
或 any
时,您应该避免将 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 举报,一经查实,本站将立刻删除。