将行向量转换为稀疏矩阵的 inptrs 的快速矢量化方法?

nar*_*ssa 4 python arrays numpy scipy sparse-matrix

对于稀疏矩阵,我们通常传入列索引 ( indices) 和一个indptr向量来索引indices向量,以便它们indices[indptr[i]:indptr[i+1]]i稀疏矩阵中行的元素。

是否有一个快速的、矢量化的、最好是 numpy 的解决方案来将连续行索引的向量转换为indptrPython 中的一个?

例如,如果这是我的rows索引向量:[0,1,1,2,2,2,3,5]...

indptr矢量将是[0,1,3,6,7,7,8]其中重复7因为行向量丢失行4。

我可以使用一个简单的循环来做到这一点:

for i in range(len(rows)):
    indptr[rows[i]+1] += 1
    indptr=np.cumsum(indptr)
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有更快的矢量化方法来做到这一点?

Ehs*_*san 6

我想你要找的是这个:

np.bincount(rows).cumsum()
#[1 3 6 7 7 8]
Run Code Online (Sandbox Code Playgroud)

如果矩阵底部的行可能为空,只需将其添加为参数bincount(根据@CJR 的建议):

np.bincount(rows, minlength=num_rows).cumsum()
#[1 3 6 7 7 8]
Run Code Online (Sandbox Code Playgroud)

您可能还想0在前面插入一个。什么bincount是计算每个 bin/row 中元素的数量,然后cumsum将它们相加。通过这种方式,您还将包括丢失的箱/行。

插入 0 的最佳方法可能是这样:

np.bincount(np.array(rows)+1).cumsum()
#[0 1 3 6 7 7 8]
Run Code Online (Sandbox Code Playgroud)

或者您可以直接通过以下方式进行:

np.insert(np.bincount(rows).cumsum(),0,0)
#[0 1 3 6 7 7 8]
Run Code Online (Sandbox Code Playgroud)