scipy 求稀疏矩阵的前n个值

9rygscc1  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(204)

我有一个CSR格式的scipy稀疏矩阵,大小为72665x72665,因此将该矩阵转换为稠密矩阵进行运算是不切实际的(该矩阵的稠密表示大约为40千兆字节)。该矩阵是对称的,大约有8200万个非零元素(约1.5%)。
我想做的是,对于每一行,我想得到最大的N个值的索引。如果这是一个numpy数组,我会用np.argpartition这样做:

for row in matrix:
        top_n_idx = np.argpartition(row,-n)[-n:]

对于稀疏矩阵,有没有类似的方法?

kd3sttzy

kd3sttzy1#

改进了Paul Panzer的解决方案。现在它可以处理任何行的值小于n的情况。

def top_n_idx_sparse(matrix, n):
    """Return index of top n values in each row of a sparse matrix."""
    top_n_idx = []
    for le, ri in zip(matrix.indptr[:-1], matrix.indptr[1:]):
        n_row_pick = min(n, ri - le)
        top_n_idx.append(
            matrix.indices[
                le + np.argpartition(matrix.data[le:ri], -n_row_pick)[-n_row_pick:]
            ]
        )
    return top_n_idx

"它能做什么"
matrix.indptr给出了存储在data数组中的每一行的开始索引。因此(lr, ri)是每一行中非零值的数据索引的范围。matrix.data[le:ri]给出了该行的非零值。将其传递给np.argpartition(..., -n_row_pick)将给出本地索引,该本地索引将从后面对最大的n_row_pick元素的行进行排序。[-n_row_pick:]选择这些局部索引。然后le +将这些局部索引移回到数据数组中的索引。最后,将其传递给matrix.indices以获得矩阵空间中最大的n值索引。

suzh9iv8

suzh9iv82#

直接使用CSR并假设每行中有足够多的正非零值,您可以写出:

for le, ri in zip(matrix.indptr[:-1], matrix.indptr[1:]):
    top_n_idx = matrix.indices[le + np.argpartition(matrix.data[le:ri], -n)[-n:]]

相关问题