【问题标题】:Updating a coo matrix on the fly with scipy使用 scipy 即时更新 coo 矩阵
【发布时间】:2017-04-11 14:16:24
【问题描述】:

搜索该站点后,我没有找到解决此问题的方法。它很简单,我想更新一个已经存在的 coo 稀疏矩阵。所以假设我已经启动了一个 coo 矩阵:

from scipy.sparse import coo_matrix
import numpy as np
row  = np.array([0, 3, 1, 0])
col  = np.array([0, 3, 1, 2])
data = np.array([4, 5, 7, 9])
a=coo_matrix((data, (row, col)), shape=(4, 4)).toarray()
array([[4, 0, 9, 0],
      [0, 7, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 5]])

很好,但是如果我只想要一个空的稀疏数组并仅使用形状启动它,然后多次更新值怎么办。我成功的唯一方法是在我的旧矩阵中添加一个新的 coo 矩阵

a=coo_matrix((4, 4), dtype=np.int8)
a=a+coo_matrix((data, (row, col)), shape=(4, 4))
a.toarray()
array([[4, 0, 9, 0],
      [0, 7, 0, 0],
      [0, 0, 0, 0],
      [0, 0, 0, 5]])

我想多次更新这个稀疏数组。但这需要相当长的时间,因为我每次更新都调用 coo 函数。必须有更好的方法,但我觉得文档有点轻(至少我读过的)或者我只是没有看到它。

非常感谢

【问题讨论】:

    标签: python arrays numpy scipy sparse-matrix


    【解决方案1】:

    当您使用这种方式进行COO矩阵时,它将输入阵列作为矩阵的属性(提供它们是正确的类型):

    In [923]: row  = np.array([0, 3, 1, 0])
         ...: col  = np.array([0, 3, 1, 2])
         ...: data = np.array([4, 5, 7, 9])
         ...: A=sparse.coo_matrix((data, (row, col)), shape=(4, 4))
    In [924]: A
    Out[924]: 
    <4x4 sparse matrix of type '<class 'numpy.int32'>'
        with 4 stored elements in COOrdinate format>
    In [925]: A.row
    Out[925]: array([0, 3, 1, 0])
    In [926]: id(A.row)
    Out[926]: 3071951160
    In [927]: id(row)
    Out[927]: 3071951160
    

    同样用于A.colA.data

    用于显示和计算,矩阵可能会转换为@ 987654327格式,因为没有为coo格式定义这些操作中的许多操作。

    ,因为你毫无疑问,987654329 @ format没有实现索引,用于获取或设置。

    lil格式设计用于更容易的增量变化。索引更改为csr也是可能的,但它将发出警告。

    coo通常用于构建新矩阵。例如,在bmat format中,组件矩阵的coo 987654334将组件矩阵的属性组合为新阵列,然后用于构建新coo矩阵。

    逐步构建@ 987654336的好方法是将新值连接到rowcoldata arrays,然后定期构建一个新的coo。 p >

    更新dok格式: How to incrementally create an sparse matrix on python?

    putting column into empty sparse matrix

    creating a scipy.lil_matrix using a python generator efficiently

    【讨论】:

    • 我最终通过建立行,col,数据阵列和在ed的Coo矩阵构建了建议。对这个问题的好工作,真的可能是最明智的方式。谢谢。
    【解决方案2】:

    我首先认为coo_matrix 是不可变的,因为它不支持任何索引,也不支持索引分配。原来你可以直接改变你的空稀疏矩阵的底层结构:

    from scipy.sparse import coo_matrix
    import numpy as np
    row  = np.array([0, 3, 1, 0])
    col  = np.array([0, 3, 1, 2])
    data = np.array([4, 5, 7, 9])
    
    a = coo_matrix((4, 4), dtype=np.int8)
    print(a.toarray())
    
    a.row = row
    a.col = col
    a.data = data
    print(a.toarray())
    

    话虽如此,可能还有其他稀疏格式更适合这种方法。

    【讨论】:

    • 您概述的过程相当快(ns)。
    • @Canuck 感谢您的反馈。请注意,正如 hpaulj 在他们的回答中所暗示的那样:您还可以即时改变 rowcoldata,而无需每次都重新绑定 a.row 等。虽然我认为这只有在更容易改变底层数组时才有帮助(即,如果你以后还没有重新创建它们)。
    • coo 相比,使用lil 格式进行此直接设置会更舒服一些。但是我们可以研究coo_matrix 类的__init__,看看是否有任何需要注意的陷阱(正确的dtypes、正确的形状、更新nnz 等)。也就是说,它除了self.data=...之外还有什么作用。
    • @hpaulj 不,我同意,使用更少的技巧和更合适的格式应该是要走的路。由于您的答案得分更高且被接受,我的答案可能不会误导任何人。还是您的观点是我应该添加免责声明或完全删除它?老实说,我对这些稀疏类并不熟悉,所以我无法真正评估我的答案有多糟糕/危险。
    猜你喜欢
    • 2016-10-29
    • 2016-03-14
    • 2017-12-04
    • 2019-06-11
    • 2016-08-29
    • 1970-01-01
    • 2018-03-18
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多