在 scipy 中连接稀疏矩阵中的特定行

Concatenating specific rows from a sparse matrix in scipy

我有一个很大的稀疏矩阵(使用 scipy.sparse),其中有 I 行和 U 列,U 比 I 大得多。 我有一个 0:I 范围内的 U 随机数列表。 我想创建一个新的稀疏矩阵,它将是一个 U * U 稀疏矩阵,用户 u 的行将包含原始稀疏矩阵的第 i 行中的所有 U 值。 比如原矩阵是3*5的矩阵:

0,0,2,1,0
0,0,3,4,1
1,1,0,2,0

随机数列表为[0,0,2,1,2]

结果矩阵应该是:

0,0,2,1,0
0,0,2,1,0
1,1,0,2,0
0,0,3,4,1
1,1,0,2,0

我现在正在使用这个代码,非常非常慢:

for u in range(U):
    i= random_indices[u]
    if u == 0:
        output_sparse_matrix = original_sparse_matrix[i, :]
    else:
        output_sparse_matrix = vstack((output_sparse_matrix,
                                       original_sparse_matrix[i, :]))

关于如何更快地完成这项工作有什么建议吗?

更新 我使用了 Jérôme Richard 的建议,但是在一个循环中——因为我遇到了内存不足的错误。这是有效的解决方案:

bins = np.array_split(random_indices, 10)
output_sparse_matrix = original_sparse_matrix[bins[0]]

for bin in bins[1:10]:
   output_sparse_matrix = vstack((output_sparse_matrix ,original_sparse_matrix[bin]))

vstack 为每次迭代创建一个新矩阵。这是减速的主要原因,因为算法的复杂度是 O(U^3)。您可以只将新行附加到 Python 列表中,然后 vstack 行列表。或者,更好的方法是使用以下 Numpy 表达式:

original_sparse_matrix[random_indices, :]

这可能不会更快,但您可以尝试使用花式索引:

output_sparse_matrix = input_sparse_matrix[random_indices]

如果 random_indices 是一个列表,上面应该给出所需的结果。

将此应用于您的原始示例:

from scipy.sparse import csr_matrix

a = csr_matrix([[0,0,2,1,0],
[0,0,3,4,1],
[1,1,0,2,0]])

indices =  [0,0,2,1,2]


output_matrix = a[indices]

print(output_matrix.todense())