在csr_matrix中添加一列零
我有一个 MxN 的稀疏 csr_matrix
矩阵,我想在这个矩阵的右边添加几列全是零的列。原则上,indptr
、indices
和 data
这几个数组应该保持不变,所以我只想改变矩阵的尺寸。不过,这似乎没有现成的方法可以做到。
>>> A = csr_matrix(np.identity(5), dtype = int)
>>> A.toarray()
array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]])
>>> A.shape
(5, 5)
>>> A.shape = ((5,7))
NotImplementedError: Reshaping not implemented for csr_matrix.
而且,把一个零矩阵横向拼接在一起似乎也不太管用。
>>> B = csr_matrix(np.zeros([5,2]), dtype = int)
>>> B.toarray()
array([[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]])
>>> np.hstack((A,B))
array([ <5x5 sparse matrix of type '<type 'numpy.int32'>'
with 5 stored elements in Compressed Sparse Row format>,
<5x2 sparse matrix of type '<type 'numpy.int32'>'
with 0 stored elements in Compressed Sparse Row format>], dtype=object)
这就是我最终想要达到的效果。有没有什么快速的方法可以改变我的 csr_matrix
的形状,而不需要把里面的所有东西都复制一遍呢?
>>> C = csr_matrix(np.hstack((A.toarray(), B.toarray())))
>>> C.toarray()
array([[1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0]])
2 个回答
9
你可以使用 scipy.sparse.vstack
或 scipy.sparse.hstack
来更快地完成这个操作:
from scipy.sparse import csr_matrix, vstack, hstack
B = csr_matrix((5, 2), dtype=int)
C = csr_matrix((5, 2), dtype=int)
D = csr_matrix((10, 10), dtype=int)
B2 = vstack((B, C))
#<10x2 sparse matrix of type '<type 'numpy.int32'>'
# with 0 stored elements in COOrdinate format>
hstack((B2, D))
#<10x12 sparse matrix of type '<type 'numpy.int32'>'
# with 0 stored elements in COOrdinate format>
请注意,输出结果是一个 coo_matrix
,它可以高效地转换成 CSR
或 CSC
格式。
6
你想做的事情其实不是numpy或scipy理解的那种“重塑”(reshape)。不过针对你的具体情况,你可以创建一个新的CSR矩阵,重新利用你原来的矩阵中的data
、indices
和indptr
,而不需要复制它们:
import scipy.sparse as sps
a = sps.rand(10000, 10000, density=0.01, format='csr')
In [19]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr),
... shape=(10000, 10020), copy=True)
100 loops, best of 3: 6.26 ms per loop
In [20]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr),
... shape=(10000, 10020), copy=False)
10000 loops, best of 3: 47.3 us per loop
In [21]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr),
... shape=(10000, 10020))
10000 loops, best of 3: 48.2 us per loop
所以如果你不再需要原来的矩阵a
,因为默认情况下是copy=False
,你只需要这样做:
a = sps.csr_matrix((a.data, a.indices, a.indptr), shape=(10000, 10020))