繁体   English   中英

改进Python中矩阵计算的执行时间

[英]Improving the execution time of matrix calculations in Python

我处理大量数据,这段代码的执行时间非常重要。 每次迭代的结果都是相互依赖的,因此很难并行实现。 如果有更快的方法来实现此代码的某些部分,那将是非常棒的,例如:

  • 找到矩阵及其索引中的最大元素
  • 使用另一行/列中的max更改行/列中的值
  • 删除特定的行和列

填充weights矩阵非常快。

代码执行以下操作:

  • 它包含word_list单词列表的列表,其中包含count元素。 在开始时,每个单词都是一个单独的列表。
  • 它包含浮点值weights二维列表( count x count )(下三角矩阵, i>=j的值为零)
  • 在每次迭代中,它执行以下操作:
    • 它找到具有最相似值的两个单词(矩阵中的最大元素及其索引)
    • 它合并了它们的行和列,从而在每个单元格中保存了两个更大的值
    • 它合并word_list的相应单词列表。 它将两个列表保存在索引较小的列表( max_j )中,并删除索引较大的列表( max_i )。
  • 如果最大值小于给定的THRESHOLD则停止

我可能会想到一个不同的算法来完成这个任务,但我现在没有任何想法,如果至少有一个小的性能改进会很好。

我尝试使用NumPy,但效果更差。

weights = fill_matrix(count, N, word_list)
while 1:
    # find the max element in the matrix and its indices 
    max_element = 0
    for i in range(count):
        max_e = max(weights[i])
        if max_e > max_element:
            max_element = max_e
            max_i = i
            max_j = weights[i].index(max_e)

    if max_element < THRESHOLD:
        break

    # reset the value of the max element
    weights[max_i][max_j] = 0

    # here it is important that always max_j is less than max i (since it's a lower triangular matrix)
    for j in range(count):
        weights[max_j][j] = max(weights[max_i][j], weights[max_j][j])

    for i in range(count):
        weights[i][max_j] = max(weights[i][max_j], weights[i][max_i])

    # compare the symmetrical elements, set the ones above to 0
    for i in range(count):
        for j in range(count):
            if i <= j:
                if weights[i][j] > weights[j][i]:
                    weights[j][i] = weights[i][j]
                weights[i][j] = 0

    # remove the max_i-th column
    for i in range(len(weights)):
        weights[i].pop(max_i)

    # remove the max_j-th row
    weights.pop(max_i)

    new_list = word_list[max_j]
    new_list += word_list[max_i]
    word_list[max_j] = new_list

    # remove the element that was recently merged into a cluster
    word_list.pop(max_i)
    count -= 1

这可能有所帮助:

def max_ij(A):
    t1 = [max(list(enumerate(row)), key=lambda r: r[1]) for row in A]
    t2 = max(list(enumerate(t1)), key=lambda r:r[1][1])
    i, (j, max_) = t2
    return max_, i, j

这取决于你想要投入多少工作,但如果你真的关心速度,你应该看看Cython 快速入门教程提供了一些示例,从35%的加速到惊人的150倍加速(您需要付出一些额外的努力)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM