【问题标题】:efficient way to iterate through coo_matrix elements ordered by column?遍历按列排序的 coo_matrix 元素的有效方法?
【发布时间】:2018-02-22 20:19:51
【问题描述】:

我有一个scipy.sparse.coo_matrix 矩阵,我想将其转换为每列的位集以进行进一步计算。 (出于示例的目的,我在 100Kx1M 上进行测试)。

我目前正在做这样的事情:

bitsets = [ intbitset() for _ in range(matrix.shape[1]) ]
for i,j in itertools.izip(matrix.row, matrix.col):
  bitsets[j].add(i)

这可行,但 COO 矩阵按行迭代值。理想情况下,我想按列进行迭代,然后一次构建位集,而不是每次都添加到不同的位集。

找不到基于列迭代矩阵的方法。有吗?

我不介意转换为其他稀疏格式,但找不到有效迭代矩阵的方法。 (在 CSC 矩阵上使用 nonzero() 已被证明效率极低...)

谢谢!

【问题讨论】:

  • nonzero 在稀疏矩阵上只返回 coo 行/列,无论格式如何。检查它的代码。通常coo 格式的元素是无序的。与csrcsc 之间的转换可能按行或列排序。
  • 谢谢!。 m.tocsc().tocoo() 然后遍历 row/col 给了我想要的。

标签: python scipy sparse-matrix


【解决方案1】:

制作一个小的稀疏矩阵:

In [82]: M = sparse.random(5,5,.2, 'coo')*2
In [83]: M
Out[83]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>'
    with 5 stored elements in COOrdinate format>
In [84]: print(M)
  (1, 3)    0.03079661961875302
  (0, 2)    0.722023291734881
  (0, 3)    0.547594065264775
  (1, 0)    1.1021150713641839
  (1, 2)    0.585848976928308

print 以及 nonzero 返回 rowcol 数组:

In [85]: M.nonzero()
Out[85]: (array([1, 0, 0, 1, 1], dtype=int32), array([3, 2, 3, 0, 2], dtype=int32))

转换为csr 对行(但不一定是列)进行排序。 nonzero 转换回 coo 并以新顺序返回行和列。

In [86]: M.tocsr().nonzero()
Out[86]: (array([0, 0, 1, 1, 1], dtype=int32), array([2, 3, 0, 2, 3], dtype=int32))

我要说转换为csc 对列进行排序,但它看起来不像:

In [87]: M.tocsc().nonzero()
Out[87]: (array([0, 0, 1, 1, 1], dtype=int32), array([2, 3, 0, 2, 3], dtype=int32))

对 csr 的转置产生一个 csc:

In [88]: M.tocsr().T.nonzero()
Out[88]: (array([0, 2, 2, 3, 3], dtype=int32), array([1, 0, 1, 0, 1], dtype=int32))

我没有完全理解您想要做什么,或者您为什么想要列排序,但lil 格式可能会有所帮助:

In [90]: M.tolil().rows
Out[90]: 
array([list([2, 3]), list([0, 2, 3]), list([]), list([]), list([])],
      dtype=object)
In [91]: M.tolil().T.rows
Out[91]: 
array([list([1]), list([]), list([0, 1]), list([0, 1]), list([])],
      dtype=object)

一般来说,稀疏矩阵的迭代很慢。 csrcsc 格式的矩阵乘法是最快的运算。许多其他操作间接利用了它(例如行总和)。另一组相对较快的操作是可以直接使用data 属性的操作,无需关注行或列值。

coo 不实现索引或迭代。 csrlil 实现这些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-03
    • 2020-07-14
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多