切片numpy
数组时,我们获得了对应数据的视图。但是,scipy.sparse
中的稀疏矩阵似乎并非如此。尽管the docs简短地提到了对lil_matrix
类的切片,但尚不清楚如何(或是否)可以获取数据视图。
至少通过使用以下示例脚本,我未能成功获得稀疏矩阵的视图:
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
。
答案 0 :(得分:1)
我会部分地吃我的话。有一种lilmatrix
getrowview
方法(但没有getcolview
)。
lil
矩阵具有2个对象dtype数组属性data
和rows
。两者都包含列表,每行一个。
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。
此view
之所以有效,是因为对象数组包含指针。与列表中的指针一样,它们可以共享。而且,如果操作正确,可以就地修改此类列表。
我是通过在view
文档上对lil_matrix
进行页面搜索来发现这一点的。我找不到其他格式的相似之处。
有些csr
格式的数字函数可直接与.data
属性一起使用。如果您不更改稀疏性,而只想修改非零值,则可以这样做。并且可以在适当位置修改该属性。在有限的情况下,可以构造一个新的稀疏矩阵来共享另一个数据属性的切片,但是它不像ndarray
切片那样普遍。
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]])
按照此模型,我可以创建“ advanced-index view, something that
ndarray”不起作用:
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]])