tod*_*le3 18 python numpy scipy sparse-matrix
我通常使用
matrix[:, i:]
Run Code Online (Sandbox Code Playgroud)
它看起来不像我预期的那么快.
Sau*_*tro 15
如果要获得稀疏矩阵作为输出,则行切片的最快方法是使用csr
类型,对于列切片csc
,如此处详述.在这两种情况下,您只需要做您目前正在做的事情:
matrix[l1:l2,c1:c2]
Run Code Online (Sandbox Code Playgroud)
如果你想要另一种类型作为输出,可能会更快.在另一个答案中,解释了许多用于切割矩阵的方法以及它们的不同时序的比较.例如,如果您想要一个ndarray
输出,那么最快的切片是:
matrix.A[l1:l2,c1:c2]
Run Code Online (Sandbox Code Playgroud)
要么:
matrix.toarray()[l1:l2,c1:c2]
Run Code Online (Sandbox Code Playgroud)
比以下快得多:
matrix[l1:l2,c1:c2].A #or .toarray()
Run Code Online (Sandbox Code Playgroud)
我发现scipy.sparse.csr_matrix
通过滚动您自己的行索引器可以更快地进行广告中的快速行索引。这是想法:
class SparseRowIndexer:
def __init__(self, csr_matrix):
data = []
indices = []
indptr = []
# Iterating over the rows this way is significantly more efficient
# than csr_matrix[row_index,:] and csr_matrix.getrow(row_index)
for row_start, row_end in zip(csr_matrix.indptr[:-1], csr_matrix.indptr[1:]):
data.append(csr_matrix.data[row_start:row_end])
indices.append(csr_matrix.indices[row_start:row_end])
indptr.append(row_end-row_start) # nnz of the row
self.data = np.array(data)
self.indices = np.array(indices)
self.indptr = np.array(indptr)
self.n_columns = csr_matrix.shape[1]
def __getitem__(self, row_selector):
data = np.concatenate(self.data[row_selector])
indices = np.concatenate(self.indices[row_selector])
indptr = np.append(0, np.cumsum(self.indptr[row_selector]))
shape = [indptr.shape[0]-1, self.n_columns]
return sparse.csr_matrix((data, indices, indptr), shape=shape)
Run Code Online (Sandbox Code Playgroud)
也就是说,可以通过将每一行的非零值存储在单独的数组中(每行具有不同的长度)并将所有这些行数组放入一个对象类型的数组中来利用 numpy 数组的快速索引(允许每一行具有不同的大小),可以有效地索引。列索引的存储方式相同。该方法与标准 CSR 数据结构略有不同,标准 CSR 数据结构将所有非零值存储在单个数组中,需要查找以查看每行的开始和结束位置。这些查找会减慢随机访问的速度,但对于检索连续行应该是有效的。
我的矩阵mat
是一个 1,900,000x1,250,000 的矩阵,csr_matrix
有 400,000,000 个非零元素。
ilocs
是一个包含 200,000 个随机行索引的数组。
>>> %timeit mat[ilocs]
2.66 s ± 233 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Run Code Online (Sandbox Code Playgroud)
相比:
>>> row_indexer = SparseRowIndexer(mat)
>>> %timeit row_indexer[ilocs]
59.9 ms ± 4.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
与布尔掩码相比,当使用花哨的索引时, SparseRowIndexer 似乎更快。
归档时间: |
|
查看次数: |
13958 次 |
最近记录: |