开发者社区> 问答> 正文

重写numpy中的循环以加快执行速度

我正在编写一个函数,该函数接受长度为200的numpy数组a和大小为200 x 200的矩阵M,并执行以下操作:

for i in range(len(a)):
    x = a[i]
    for j in range(len(a)):
        y = a[j]
        z = M[i][j]
        d[i][j] = 2 * z/(y+x)
return d

如何对这段代码进行矢量化处理以提高运行时间?

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 12:24:11 393 0
1 条回答
写回答
取消 提交回答
  • Numpy的ufunc都具有external方法,以在两个数组上“交叉”执行操作。因此,为了避免大多数中间计算并尽可能向量化:

    def f(M, a):
        return 2 * M / np.add.outer(a, a)
    
    • 回答旧版本的问题(左,因为它仍然有用)

    对于这样的事情,我发现最好总是分步进行,并尝试找到正确的einsum表达式。

    # the definition given in the original question,
    # before the z / (y + x) update
    def f0():
        d = np.empty((3,3))
        for i in range(len(a)):
            x = a[i]
            for j in range(len(a)):
                y = a[j]
                z = M[i][j]
                d[i][j] = 2 * x/(y+z)
        return d
    
    # rewrite things inlined
    def f1():
        d = np.empty((3,3))
        for i in range(len(a)):
            for j in range(len(a)):
                d[i, j] = 2 * a[i]/(a[j] + M[i, j])
        return d
    
    # factor out broadcasting
    def f2():
        d = np.empty((3,3))
        for i in range(len(a)):
            m = a + M[i, :]
            for j in range(len(a)):
                d[i,j] = 2 * a[i]/m[j]
        return d
    
    # more broadcasting
    def f3():
        d = np.empty((3,3))
        m = a + M
        for i in range(len(a)):
            for j in range(len(a)):
                d[i,j] = 2 * a[i]/m[i,j]
        return d
    
    # now turn loops into einsums
    def f4():
        d = np.empty((3,3))
        m = 1/(a + M)
        d[:,:] = 2 * np.einsum('i,ij->ij', a, m)
        return d
    
    # collect everything
    def f5():
        return np.einsum('i,ij->ij', a, 2 / (a + M))
    

    回答来源:stackoverflow

    2020-03-24 12:24:18
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
建立联系方法之一 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载

相关实验场景

更多