如何获得稀疏矩阵的视图? [英] How to get views on sparse matrices?
问题描述
在对 numpy
数组进行切片时,我们会获得相应数据的视图.然而,来自 scipy 的稀疏矩阵似乎并非如此.sparse
.尽管文档 简要提到了lil_matrix
类不清楚如何(或是否)获得数据视图.
When slicing a numpy
array we obtain a view on the corresponding data. However that doesn't seem to be the case with sparse matrices from scipy.sparse
. Although the docs briefly mention slicing for the lil_matrix
class it's not clear how (or if) one can obtain views on the data.
至少通过使用以下示例脚本,我没有成功获得稀疏矩阵的视图:
At least by using the following sample script I wasn't successful in obtaining views of sparse matrices:
import numpy as np
from scipy.sparse import lil_matrix
def test(matrix):
print('\n=== Testing {} ==='.format(type(matrix)))
a = matrix[:, 0]
b = matrix[0, :]
a[0] = 100
M[0, 1] = 200
M[1, 0] = 200
print('a = '); print(a)
print('b = '); print(b)
M = np.arange(4).reshape(2, 2) + 1
S = lil_matrix(M)
test(M)
test(S)
输出:
=== Testing <class 'numpy.ndarray'> ===
a =
[100 200]
b =
[100 200]
=== Testing <class 'scipy.sparse.lil.lil_matrix'> ===
a =
(0, 0) 100
(1, 0) 3
b =
(0, 0) 1
(0, 1) 2
<小时>
测试 Python 3.6.6, numpy==1.14.5, scipy==1.1.0
.
推荐答案
我会吃掉我的话 - 部分.有一个 lilmatrix
getrowview
方法(但不是 getcolview
).
I'll eat my words - partially. There is a lilmatrix
getrowview
method (but not a getcolview
).
一个 lil
矩阵有 2 个对象 dtype 数组属性,data
和 rows
.两者都包含列表,每行一个.
A lil
matrix has 2 object dtype array attributes, data
and rows
. Both contain lists, one for each row.
def getrow(self, i):
"""Returns a copy of the 'i'th row.
"""
i = self._check_row_bounds(i)
new = lil_matrix((1, self.shape[1]), dtype=self.dtype)
new.rows[0] = self.rows[i][:]
new.data[0] = self.data[i][:]
return new
def getrowview(self, i):
"""Returns a view of the 'i'th row (without copying).
"""
new = lil_matrix((1, self.shape[1]), dtype=self.dtype)
new.rows[0] = self.rows[i]
new.data[0] = self.data[i]
return new
一些测试表明修改行视图的元素确实会影响父视图,并且 v.v.
A little testing shows that modifying elements of the row view does affect the parent, and v.v.
这个 view
工作是因为对象数组包含指针.与列表中的指针一样,它们可以共享.如果做得好,这样的列表可以就地修改.
This view
works because an object array contains pointers. As with pointers in a list, they can be shared. And if done right, such a list can be modified in-place.
我通过在 lil_matrix
文档中对 view
进行页面搜索发现了这一点.我没有发现其他格式的类似内容.
I found this by doing a page search for view
on the lil_matrix
documentation. I don't find anything similar for the other formats.
csr
格式中有一些数字函数可以直接使用 .data
属性.如果您不更改稀疏性并且只想修改非零值,则这是可能的.并且可以就地修改该属性.在有限的情况下,可能会构造一个新的稀疏矩阵,该矩阵共享另一个数据属性的切片,但它不会像 ndarray
切片那样通用.
There are numerical functions on the csr
format that work directly with the .data
attribute. This is possible if you aren't changing sparsity, and only want to modify the nonzero values. And it is possible to modify that attribute in place. In limited cases it might be possible to construct a new sparse matrix that shares slices of the data attribute of another, but it would not be anything as general as ndarray
slicing.
In [88]: M = sparse.lil_matrix((4,10),dtype=int)
In [89]: M[0,1::2] = 1
In [90]: M[1,::2] = 2
In [91]: M1 = M.getrowview(0)
In [92]: M1[0,::2] = 3
In [94]: M.A
Out[94]:
array([[3, 1, 3, 1, 3, 1, 3, 1, 3, 1],
[2, 0, 2, 0, 2, 0, 2, 0, 2, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [95]: M[0,1::2] = 4
In [97]: M1.A
Out[97]: array([[3, 4, 3, 4, 3, 4, 3, 4, 3, 4]])
按照这个模型,我可以制作一个高级索引视图,这是
ndarray"不能做的:
Following this model I could make an 'advanced-indexview, something that
ndarray` doesn't do:
In [98]: M2 = sparse.lil_matrix((2,10), dtype=int)
In [99]: M2.rows[:] = M.rows[[0,3]]
In [100]: M2.data[:] = M.data[[0,3]]
In [101]: M2.A
Out[101]:
array([[3, 4, 3, 4, 3, 4, 3, 4, 3, 4],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [102]: M2[:,::2] *= 10
In [103]: M2.A
Out[103]:
array([[30, 4, 30, 4, 30, 4, 30, 4, 30, 4],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [104]: M1.A
Out[104]: array([[30, 4, 30, 4, 30, 4, 30, 4, 30, 4]])
这篇关于如何获得稀疏矩阵的视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!