python性能提示 - 涉及比较的循环

时间:2015-10-31 15:14:53

标签: python performance numpy

我是python的新手,我正在尝试通过连续优化我已编写的天真代码块来了解它的工作原理。

以下函数涉及一个循环,仅当数据结构的值满足某些条件时才对浮点列表的元素执行操作。我想知道是否有人可以评论(1)改善此循环性能的方法和(2)我所描述的循环类型的一般特征使其或多或少地适合于改进它的不同方法。下面我已经包含了我正在使用的循环的最小版本。

关于下面使用的变量的一些注释:

#p is a small integer (say, p=10)
#index1 is an integer between 0 and p
#k is an integer between 0 and, say, kmax=100
#mat1 is a list of list of floats whose size is [kmax,p],
#    with all values initialized to 0.0. 
#    mat1 is changed by the loop below
#mat2 is a list of list of floats whose size is [kmax,p]
#    with all values initialized to -2e10. 
#    mat2 is changed by other parts of the program 

另外,如果重要的是,在我的代码中,这是一个类的所有部分,所以有“自我”。变量的陈述。我已经读过python函数可以更好地处理局部变量;这如何转化为类构造?

def greatFunction(index1,k):                          
    index2 = index1
    for j in range(p):                        
        if (mat2[k][index2] > -1e10):         
            mat1[k][j] = mat1[k][j] + mat2[k][index1]*mat2[k][index2]
        index2 = index2 - 1
        if(index2 < 0):
            index2 = index2 + p

根据我的阅读,我认为这将是用nparrays替换列表列表的主要候选者(在类本身中,不转换函数中的东西)并使用掩码来处理布尔条件。但是,我写的numpy版本比上面的vanilla python实现慢。任何帮助既加速代码,但更重要的是帮助我理解为什么以及如何用更好的结构替换这样的循环将非常感激。谢谢!

1 个答案:

答案 0 :(得分:0)

看起来index2index1变为0,逐渐减少1,然后循环回到p-1然后再次开始减少。这基本上是modulo operation,因此可以使用np.mod进行模拟,以便在每次迭代时将index2作为列索引。然后,我们索引到k-th的{​​{1}}行,并使用上一步中的列索引来获取我们目的所需的所有元素。将这些元素与阈值(在我们的例子中为mat2)进行比较,为我们提供一个掩码,用于从该行中选择元素,并在使用{缩放后将相应的元素设置为输出数组-1e10 {1}}。

由于您正在使用NumPy数组,我假设您已将mat1mat2[k][index1]转换为具有np.array()的NumPy数组。

此外,正如评论中所述,如果mat1的所有值都已初始化为mat2,则mat2永远不会是-2e10,因此在特定情况下, mat2[k][index2] > -1e10会保留其true。因此,为了一般性地解释如何对这种情况进行矢量化,我假设mat1代替随机数。实现看起来像这样 -

zeros