繁体   English   中英

用数组中的元素乘以 Python 稀疏矩阵的行和列

[英]Multiplying Rows and Columns of Python Sparse Matrix by elements in an Array

我有一个 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]]

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

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

我感谢您的帮助!

编辑:

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

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

要将 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())。

我希望这运行得非常快。

以下应该工作:

[[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]]

由于浮点运算的限制,数值略有偏差 如果舍入误差不可接受,请使用小数模块。

我使用这种组合:

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(乘以行)时,我复制此解决方案的第二种方法,当轴为 0(乘以列)时,我使用乘法

就地结果(轴 = 1)更有效。

暂无
暂无

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

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