在sparse 中访问块或子矩阵的规则与numpy 相同[编辑:相似]。 2 个索引数组需要是可广播的。最简单的方法是让第一个成为列向量。
我会举例说明:
In [13]: A = np.arange(24).reshape(4,6)
In [14]: M=sparse.csr_matrix(A)
In [15]: A[[[1],[2]],[1,2,3]]
Out[15]:
array([[ 7, 8, 9],
[13, 14, 15]])
In [16]: M[[[1],[2]],[1,2,3]].A
Out[16]:
array([[ 7, 8, 9],
[13, 14, 15]], dtype=int32)
In [17]: idx1=np.array([1,2])[:,None]
In [18]: idx1
Out[18]:
array([[1],
[2]])
In [19]: idx2=np.array([1,2,3])
In [20]: M[idx1, idx2].A
Out[20]:
array([[ 7, 8, 9],
[13, 14, 15]], dtype=int32)
In [21]: M[idx1, idx2] *= 2
In [22]: M.A
Out[22]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 14, 16, 18, 10, 11],
[12, 26, 28, 30, 16, 17],
[18, 19, 20, 21, 22, 23]], dtype=int32)
M[inds,:][:,inds] 在 sparse 中的问题与在 numpy 中的问题相同。对于列表inds,M[inds,:] 是原件的副本,而不是view。我已经参考 numpy.xml 中的数据缓冲区证明了这一点。我不太清楚如何用稀疏来证明它。
大致上,A[...][...] = ... 转换为 A.__getitem__(...).__setitem__(...,...)。如果A.__getitem__(...) 是一个副本,那么修改它不会修改A 本身。
实际上稀疏矩阵在视图和副本之间没有区别。大多数(如果不是全部)索引会生成一个副本。 M[:2,:] 是一个副本,尽管 A[:2,:] 是一个视图。
我还应该补充一点,更改稀疏矩阵的值是您应该谨慎行事的事情。就地乘法 (*=) 没问题。
不支持就地添加:
In [31]: M[idx1, idx2] += 2
...
NotImplementedError:
修改值可能会产生 EfficiencyWarning - 如果它将 0 值变为非零:
In [33]: M[:2, :2] = 3
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:690: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
您上一个问题的np.ix_ 答案也适用于此处。
Python - list of same columns / rows from matrix
M[np.ix_([1,2],[1,2,3])].A