python - 如何在 Numpy 中重写双循环以节省执行时间?
问题描述
我想以最有效的方式创建一个卡片组。这是具有双重 for 循环和标准列表的简单解决方案:
card = []
for figure in range(2, 15):
for suite in [1, 2, 3, 4]:
card = [figure, suite]
self.cards.append(card)
这段代码将被执行数百万次,所以我想使用 Numpy 对其进行优化。
EDIT1:我什至认为写下所有可能性并将它们放入数组中不会是最快的..
解决方案
有人在评论中击败了我,但我有一些时间信息给你。请注意,您的时间可能会有所不同,但相对时间应该相当能代表您可能看到的性能。
首先是您的代码,我将其修复为可运行:
cards = []
for figure in range(2, 15):
for suite in [1, 2, 3, 4]:
card = [figure, suite]
cards.append(card)
# 8.04 µs ± 27.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
所以 8.04 微秒是击败的时间!使用numpy.mgrid
:
import numpy as np
cards = np.mgrid[1:5, 2:15]
# 20.5 µs ± 320 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
出乎意料地慢了很多。我想知道我的系统上是否没有为 numpy 设置理想的东西。我仍然建议在您的系统上尝试它(使用%%timeit
Jupyter 笔记本中的单元魔法以便于分析)。
接下来使用itertools.product
:
import itertools as it
figures = range(2, 15)
suits = [1, 2, 3, 4]
cards = list(it.product(suits, figures))
# 2.5 µs ± 27.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
快点!最好的消息是it.product()
在调用时返回一个迭代器而不是创建列表,所以如果您稍后才需要实际的卡片列表,您可以推迟创建列表并传递迭代器。到目前为止,创建迭代器是最快的:
cards_it = it.product(suits, figures) # notice no 'list'
# 479 ns ± 9.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
这比其他任何东西都要快 5-10 倍!
推荐阅读
- javascript - 来自父级的控制模式 - React hooks | 反应带
- swift - '从初始化程序返回而不初始化所有存储的属性' Codeable 类
- ios - 当最低级别的键相同时解码嵌套的 JSON
- python - 为什么我无法访问自我。
在 pdb 里面 - python - 如何在 Python 脚本的执行过程中以复杂变量的形式(有效地)将大数据缓存在内存中?
- excel - 匹配函数内的Excel VBA索引
- tomcat8 - ClassLoader.getSystemClassLoader().getResourceAsStream() 在 Servlet 中返回 null?
- javascript - 有没有办法在渲染 hbs 部分(nodejs,mogodb,express)而不实际重新加载网页的情况下更新与部分一起发送的数据?
- sql - 为什么没有找到使用此 SQL 代码的特定组的平均值?
- python - 将视图添加到 Django