【问题标题】:Any efficient way to update very large matrix?更新非常大的矩阵的任何有效方法?
【发布时间】:2018-01-25 13:55:15
【问题描述】:

我有一个非常大的矩阵,它是一个有几百行但大约 200 万列的二维数组。我的应用程序需要用一个痛苦的约束逐行更新这个矩阵。要更新特定行,它需要等待更新之前行的所有列。而且这个过程很慢。

例如:

matrix = [[0 for x in xrange(2000000)] for y in xrange(300)]
for i in xrange(1, 300):
    for j in xrange(2000000):
        k = a random column in row i-1
        matrix[i][j] = matrix[i-1][k] * simple_function(i) # some calculation
  • 要更新 matrix[i][j] ,我需要有行 i-1 的值

我最初的想法是在每个i 轮次中使用多进程方法来并行化j 循环。但是,j 循环中的计算太轻了。进程创建成本远高于计算(我也试过进程池)。

第二个想法是使用线程,由于 GIL 的限制,它运行良好,几乎没有性能提升。

我想知道是否有任何其他方法可以加速我的代码。谢谢。

顺便说一句,我知道 Cython 可以在没有 GIL 的情况下工作。但是计算函数需要访问一个Python对象,修改原始代码需要做很多工作。

【问题讨论】:

  • 如果simple_function 的结果只依赖于i,您可以将结果存储在外部循环中一次,然后在内部循环中重复使用。 k 是什么?
  • 如果kj 的拼写错误,那么您似乎交换了ij 的迭代顺序,然后并行化j 上的最外层循环,给出每个并行作业要按行顺序处理的一大块列。正如@schwobaseggl 指出的那样,您还可以预先计算 simple_function 并在所有工作人员中使用它,假设没有讨厌的副作用。
  • 谢谢你们。我已经更新了我的问题。 Ki-1 行中的随机列。而simple_function也需要访问i-1行中的列。
  • 有什么理由不使用 python 3?你看过Scipy/Numpy吗?
  • 我不认为 Python3 或 numpy/scipy 能够解决这个问题。如果可以的话,我很想知道怎么做。

标签: python algorithm data-structures python-multiprocessing python-multithreading


【解决方案1】:

将 Numba 用于此类任务

https://numba.pydata.org/ 如果您不需要矩阵或数组,请创建一个(而不是列表列表)。我还建议看一些关于 numpy 的初学者教程。

示例代码:

import numpy as np
import numba as nb
import time

def main():
    matrix = np.random.rand(2000000,300)
    t1=time.time()
    k=100
    Testing(matrix,100)
    print(time.time()-t1)

@nb.jit(cache=True)
def Testing(matrix,k):
    for i in xrange(1, matrix.shape[0]):
        #inline your simple function (in my case np.power(i,2))
        res_of_func=np.power(i,2)
        for j in xrange(matrix.shape[1]):
            matrix[i,j] = matrix[i-1,k] * res_of_func

if __name__ == "__main__":
    main()

矩阵计算在我的机器(Haswell i7)上需要 0.5 秒。 在 Python 2 上,与 Windows 上的 numba 并行化今天不起作用。但是 jit 编译的代码应该快 100 倍左右。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2011-09-16
    相关资源
    最近更新 更多