【问题标题】:How to speed up "for loop" in Python3如何在 Python3 中加速“for循环”
【发布时间】:2020-06-01 11:22:48
【问题描述】:

下面的代码运行太慢了。我尝试使用numpy.argwhere 而不是“if 语句”来加速代码,我得到了一个非常有效的结果,但它仍然很慢。我也试过numpy.frompyfuncnumpy.vectorize 但我失败了。你有什么建议可以加快下面的代码?

import numpy as np
import time

time1 = time.time()

n = 1000000
k = 10000

velos = np.linspace(-1000, 1000, n)
line_centers = np.linspace(-1000, 1000, k)
weights = np.random.random_sample(k)
rvs = np.arange(-60, 60, 2)

m = len(rvs)
w = np.arange(10)
M = np.zeros((n, m))
for l, lc in enumerate(line_centers):
    vi = velos - lc

    for j in range(m - 1):
        w = np.argwhere((vi < rvs[j + 1]) & (vi > rvs[j])).T[0]

        M[w, j] = weights[l] * (rvs[j + 1] - vi[w]) / (rvs[j + 1] - rvs[j])
        M[w, j + 1] = weights[l] * (vi[w] - rvs[j]) / (rvs[j + 1] - rvs[j])

time2 = time.time()

print(time2 - time1)

编辑: 数组M 的大小不正确。我修好了它。

【问题讨论】:

  • 你可能想看看numba:numba.pydata.org
  • 我来看看。谢谢。
  • 如果你想使用 Numba,把所有东西写在一个简单的嵌套循环中(没有像 argwhere 这样的矢量化命令)
  • 请注意,从您的代码中删除 argwhere(例如,将其替换为常量 w=1,例如,将循环速度提高 20 倍。因此,如果您可以重写它,您的代码可能已经快很多了。嵌套循环在这里可能无关紧要。

标签: python python-3.x numpy vectorization


【解决方案1】:

这似乎是 C++ 接口可以派上用场的情况。使用 Pybind11,您可以创建将 numpy 数组作为参数、操作它们并将它们返回给 python 的 c++ 函数。这会加快你的循环。看看吧!

【讨论】:

  • 我曾想过用 C++ 编写作为包装器。但后来我想知道它是否有 python 的解决方案。 Pybind11 看起来对这个目的很有用。谢谢。
【解决方案2】:

当然很慢,你有两个嵌套循环!您需要使用向量运算重新考虑您的算法,例如,不对索引进行迭代,而是根据索引或布尔数组以及索引移位来实现。

您没有提供任何背景信息,因此任何人都很难提出有意义的建议(鉴于示例中的索引汤)。基于快速收集您的示例的一些快速建议。

  • (rvs[j + 1] - rvs[j]) 这样的表达式很容易被 numpy.ediff1d 替换。
  • 您似乎在m 的块中迭代n,也许numpy.nditer 会有用。
  • 我有一种预感,你的内部循环有一个错误,你确定你真的要迭代 range(m - 1) 吗?这意味着您正在从 0 迭代到 m-2(含),我怀疑您的意思。

如果您提供更多背景信息,我们可以提供更具体的答案。

【讨论】:

  • 我分享了原始代码中的一部分作为示例。很难解释我想用这段代码做什么,所以我没有提供足够的背景信息,抱歉。 range(m - 1) 是数组 Mj + 1 索引所必需的。我会尝试你的建议并在这里写下结果。谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-09-03
  • 2016-01-31
  • 1970-01-01
  • 2011-09-22
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多