【问题标题】:Multiplying Rows and Columns of Python Sparse Matrix by elements in an Array将 Python 稀疏矩阵的行和列乘以数组中的元素
【发布时间】:2012-10-21 05:14:07
【问题描述】:

我有一个 numpy 数组,例如:

array = [0.2, 0.3, 0.4]

(这个向量实际上是 300k 密集的,我只是用简单的例子来说明)

以及使用 Scipy 创建的稀疏对称矩阵,如下所示:

M = [[0, 1, 2]  
     [1, 0, 1]  
     [2, 1, 0]]

(表示为稠密只是为了说明;在我的实际问题中,它是一个 (300k x 300k) 稀疏矩阵)

是否可以将所有行乘以数组中的元素,然后对列进行相同的操作?

这将首先导致:

M = [[0 * 0.2, 1 * 0.2, 2 * 0.2]
     [1 * 0.3, 0 * 0.3, 1 * 0.3]
     [2 * 0.4, 1 * 0.4, 0 * 0.4]]

(行乘以数组中的元素)

M = [[0, 0.2, 0.4]
     [0.3, 0, 0.3]
     [0.8, 0.4, 0]]

然后列相乘:

M = [[0 * 0.2, 0.2 * 0.3, 0.4 * 0.4]
     [0.3 * 0.2, 0 * 0.3, 0.3 * 0.4]
     [0.8 * 0.2, 0.4 * 0.3, 0 * 0.4]]

最终结果:

M = [[0, 0.06, 0.16]
     [0.06, 0, 0.12]
     [0.16, 0.12, 0]]

我已尝试应用我在this thread 中找到的解决方案,但没有奏效;我按照建议将 M 的数据乘以数组中的元素,然后转置矩阵并应用相同的操作,但结果不正确,仍然不明白为什么!

只是指出这一点,我将运行此操作的矩阵有点大,它有 2000 万个非零元素,所以效率非常重要!

感谢您的帮助!

编辑:

按位解决方案效果很好。这里计算这个操作需要 1.72 秒,但这对我们的工作来说没问题。天呐!

【问题讨论】:

    标签: python sparse-matrix operations


    【解决方案1】:

    以下应该有效:

    [[x*array[i]*array[j] for j, x in enumerate(row)] for i, row in enumerate(M)]
    

    例子:

    >>> array = [0.2, 0.3, 0.4]
    >>> M = [[0, 1, 2], [1, 0, 1], [2, 1, 0]]
    >>> [[x*array[i]*array[j] for j, x in enumerate(row)] for i, row in enumerate(M)]
    [[0.0, 0.059999999999999998, 0.16000000000000003], [0.059999999999999998, 0.0, 0.12], [0.16000000000000003, 0.12, 0.0]]
    

    由于floating point arithmetic 的限制,值略有偏差。如果舍入误差不可接受,请使用decimal 模块。

    【讨论】:

    • Tnx 的答案。我试过了,但几分钟后它仍在处理中,我不得不停止它。有更快的解决方案吗? Tnx!
    • 您使用的是 Python 列表还是 numpy 数组?对于 Python 列表,您不会比这更快,它只会遍历嵌套列表中的每个元素。
    • 我正在使用来自 scipy 的稀疏矩阵,并且该数组是一个 numpy 向量。我在问题中表示为列表只是为了更好地说明。
    • 您应该使用该信息编辑您的问题,因为听起来 numpy 解决方案是您获得所需速度的最佳选择。
    • 刚刚做到了! Tnx 的帮助!
    【解决方案2】:

    一般来说,您希望避免循环并使用矩阵运算来提高速度和效率。在这种情况下,解决方案是简单的线性代数,或者更具体地说是矩阵乘法。

    要将 M 的列乘以数组 A,请乘以 M*diag(A)。要将 M 的行乘以 A,请乘以 diag(A)*M。两者都做:diag(A)*M*diag(A),可以通过:

    numpy.dot(numpy.dot(a, m), a)
    

    diag(A) 这里是一个除对角线有 A 外全为零的矩阵。您可以使用方法轻松创建此矩阵(例如 numpy.diag() 和 scipy.sparse.diags())。

    我希望它运行得非常快。

    【讨论】:

    • 精彩的按位!!!这工作得很好!我有点愚蠢,因为之前没有考虑过这个,哈哈,但无论如何,非常感谢,这对我有很大帮助!
    • 只是为了确保,在解决方案中,当它说“a”时,应该阅读“diag(a)”,或者制作 a = diag(a),或者制作 a = sparse.diags(a , 0) 并且它工作正常
    【解决方案3】:

    我使用这个组合:

    def multiply(matrix, vector, axis):
        if axis == 1:
            val = np.repeat(array, matrix.getnnz(axis=1))
            matrix.data *= val
        else:
            matrix = matrix.multiply(vector)
        return matrix
    

    当轴为1(乘以行)时,我复制this solution的第二种方法, 当轴为0(乘以列)时,我使用multiply

    就地结果(axis=1)效率更高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-16
      • 2012-08-27
      • 2021-08-21
      • 2011-11-20
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      相关资源
      最近更新 更多