【问题标题】:Speeding up loops over a Numpy array加速 Numpy 数组上的循环
【发布时间】:2011-05-12 03:23:11
【问题描述】:

在我的代码中,我有一个 for 循环,该循环对多维 numpy 数组进行索引,并使用每次迭代获得的子数组进行一些操作。看起来是这样的

for sub in Arr:
  #do stuff using sub

现在使用sub 完成的工作是完全矢量化的,所以它应该是高效的。另一方面,这个循环迭代了大约~10^5 次并且是瓶颈。你认为我会通过将这部分卸载到 C 来获得改进吗?我有点不愿意这样做,因为 do stuff using sub 使用广播、切片、智能索引技巧,用普通 C 编写会很乏味。我也欢迎关于在将计算卸载到 C 时如何处理广播、切片、智能索引的想法和建议。

【问题讨论】:

  • 我不确定,但在我看来,您正在使用经过优化的流程来达到预期目的。我没有理由不使用它...
  • @soandos 你能详细说明一下吗?我不太了解您,尤其是您评论中的“它”指的是什么。
  • @san: for * in Arr 被设计成非常擅长遍历数组。看起来,人们应该使用它。我不知道它会产生多大的差异,老实说,因为 10^5 次并不是那么多(在标准的 1.66 ghz 计算机上,一个循环每秒可以通过超过 3.3 亿次交互)和所以一个更好的问题是:你怎样才能加快你的“做事”
  • 你玩过 Cython 吗?它不会修复你的算法,但它会去除大量的 python 开销。
  • @san - 也许您甚至不必遍历数组。如果您通过do stuff 向我们展示更多详细信息,我们可以找到没有循环的更好解决方案。

标签: python for-loop numpy


【解决方案1】:

如果您不能“矢量化”整个操作并且循环确实是瓶颈,那么我强烈建议使用 Cython。我最近一直在涉足它,它使用起来很简单,并且与 numpy 有一个不错的界面。对于像 langevin 集成器这样的东西,我看到 numpy 中的一个体面的实现速度提高了 115 倍。请参阅此处的文档:

http://docs.cython.org/src/tutorial/numpy.html

我还建议查看以下paper

只需键入输入数组和循环计数器,您可能会看到令人满意的加速,但如果您想充分利用 cython 的潜力,那么您将不得不对等效的广播进行硬编码。

【讨论】:

    【解决方案2】:

    你可以看看scipy.weave。您可以使用scipy.weave.blitz 将您的表达式透明地转换为C++ 代码并运行它。它会自动处理切片并删除临时对象,但您声称 for 循环的主体不会创建临时对象,因此您的里程可能会有所不同。

    但是,如果您想用更高效的方法替换整个 for 循环,则可以使用 scipy.inline。缺点是您必须编写C++ 代码。这应该不会太难,因为您可以使用非常接近 numpy 数组表达式的 Blitz++ 语法。直接支持切片,但不支持广播。

    有两种解决方法:

    1. 是使用numpy-C api,使用多维迭代器。他们透明地处理广播。但是,您正在调用 Numpy 运行时,因此可能会有一些开销。另一种选择,可能是更简单的选择是使用通常的矩阵表示法进行广播。广播操作可以写成向量全为1的外积。好在Blitz++实际上不会在内存中创建这个临时广播数组,它会弄清楚如何将它包装到一个等效的循环中。

    2. 对于第二个选项,请查看 http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC88 以获取索引占位符。只要您的矩阵的维数少于 11,就可以了。此链接显示了如何使用它们来形成外部产品http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC99(搜索外部产品以转到文档的相关部分)。

    【讨论】:

      【解决方案3】:

      除了使用 Cython,您还可以在 Fortran 中编写瓶颈部分。然后使用 f2py 编译成 Python .pyd 文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-08
        • 2017-08-21
        • 2020-04-12
        • 2019-08-11
        • 2015-10-27
        • 2016-10-14
        • 2017-01-15
        • 2021-08-06
        相关资源
        最近更新 更多