迭代按列排序的coo_matrix元素的有效方法?

时间:2018-02-22 20:19:51

标签: python scipy sparse-matrix

我有一个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矩阵按行迭代值。理想情况下,我想按列迭代,然后立即构建bitset,而不是每次都添加到不同的bitset。

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

制作一个小的稀疏矩阵:

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实施这些。