【问题标题】:Accessing / modifying submatrix of sparse scipy matrix访问/修改稀疏 scipy 矩阵的子矩阵
【发布时间】:2016-02-03 03:21:41
【问题描述】:

假设我有一些 Scipy 稀疏 csr 矩阵 A 和一组索引 inds=[i_1,...,i_n]。我可以通过A[inds,:][:,inds] 访问inds 中给出的行和列给出的子矩阵。但我不知道如何修改它们。以下所有失败(即不更改矩阵值):

  • A[inds,:][:,inds] *= 5.0
  • (A[inds,:][:,inds]).multiply(5.0)
  • A[inds,:][:,inds] = 5.0

有没有简单的方法来修改稀疏矩阵的子矩阵?

【问题讨论】:

  • 为什么要使用[][] 风格的索引?为什么不只是一组索引括号?
  • 因为A[inds,inds] != A[inds,:][:,inds]。这就是我学习如何访问整个子矩阵的方法。

标签: python python-2.7 scipy


【解决方案1】:

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 中的问题相同。对于列表indsM[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

【讨论】:

  • 谢谢你,有趣的微妙之处。我习惯于 C++,从编码的角度来看,任何引用、指针或副本都是显式的。我正在使用 python 进行一些原型设计,这非常棒,但我需要更好地解决这类问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2017-07-21
  • 2011-11-28
  • 2017-07-02
  • 2011-03-07
  • 2014-10-15
相关资源
最近更新 更多