【问题标题】:Vectorizing operations in nested loops: Python嵌套循环中的向量化操作:Python
【发布时间】:2015-09-15 18:57:32
【问题描述】:

我有 2D numpy 数组,我需要两个嵌套循环来迭代它的每个元素。我想对嵌套循环进行一些矢量化,但我一直收到错误提示,

j= np.arange (0,x.shape [1])
IndexError: tuple index out of range

这些是原始的嵌套循环:

for k in range(A.shape[0]):
        for j in range(A.shape[1]):
            A[k,j] = method1(x[k],x[j],a,c0,c1)

这就是我尝试根据这个答案进行矢量化的方法,https://codereview.stackexchange.com/questions/17702/python-numpy-running-15x-slower-than-matlab-am-i-using-numpy-effeciently,

j= np.arange (0, A.shape [1])
    for k in range(A.shape[0]):

            A[k,j] = method1(x[k],x[j],a,c0,c1)

我尝试更改 np.arange 中的索引,但没有成功。

谁能告诉我如何解决这个问题?

谢谢。

编辑:通过@ajcr 评论,我的错误在于这一行,j= np.arange (0,x.shape [1]),我应该使用二维数组“A”的列数作为 j = np.arange(0,A.shape [1]),但我错误地使用了一维数组x,因此出现错误。它现在工作得很好。

【问题讨论】:

  • IndexError for x.shape[1] 意味着 x 只有一个维度 - 你确定它是二维的吗?
  • 哦!我真的为这个错误道歉,我应该把它当作 j= np.arange (0,A.shape [1])。非常感谢您的评论,它现在运行得很好,比以前快得多:)
  • 我将编辑我的问题并指出错误。
  • 如果您发布method1,我们可能会为您提供更多帮助。

标签: python numpy vectorization nested-loops compiler-optimization


【解决方案1】:

由于您不提供函数本身,因此很难给您答案。如果可以将您的计算矢量化,这将是可行的方法。否则,您可以使用np.vectorize:

import numpy as np

def my_fun(x,y,a,b):
    if x > y:
        return a*x**2 + y
    else:
        return b*x**2 + a*y

vec_fun = np.vectorize(my_fun)
x = np.random.rand(100000)
y = np.random.rand(100000)

%%timeit
for xx,yy in zip(x,y):
    my_fun(xx,yy,1,2)

10 个循环,3 个循环中的最佳值:每个循环 138 毫秒

%%timeit
    vec_fun(x,y,1,2)

10 个循环,3 个循环中的最佳值:每个循环 65.4 毫秒

如果您只是循环输入参数列表,您可以使用multiprocessing.Pool 来利用您的所有内核。

编辑:正如 BlackCat 所指出的, np.vectorize 函数可能不会加快速度。如果是这种情况,我能想到的唯一解决方案是使用所有内核或切换到 Cython。

【讨论】:

  • 感谢您的清晰解释,我也会尝试您的建议。
  • 来自文档“提供vectorize 函数主要是为了方便,而不是为了性能。实现本质上是一个 for 循环。”所以这不是OP真正想要的。我的结果是循环时间为 94.8 毫秒,向量化时间为 271 毫秒,所以使用 vectorize 的版本实际上更慢。
  • 好点。我忘记了。但性能差异让我感到困惑。
  • 谢谢,实际上在我的情况下效果很好,应用矢量化后,性能时间从 61 ms 下降到 5 ms。似乎因情况而异。
  • 你检查你的计算了吗?
猜你喜欢
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 2021-07-29
相关资源
最近更新 更多