【问题标题】:How to get views on sparse matrices?如何获得稀疏矩阵的视图?
【发布时间】:2019-01-31 23:47:34
【问题描述】:

在对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

【问题讨论】:

  • 稀疏矩阵不做视图。您可以修改.data 属性的某些格式。
  • @hpaulj 你怎么知道?有这方面的文件吗?也许还有另一种与numpy语法不相似的方式?
  • 对于lil,数据表示为两个对象 dtype 数组,每行都有一个列表。其他格式使用 3 个数组或字典。没有人使用strides,这是ndarray views 的重要组成部分。

标签: python python-3.x numpy scipy


【解决方案1】:

我会吃掉我的话 - 部分。有一个lilmatrixgetrowview 方法(但没有getcolview)。

lil 矩阵有 2 个对象 dtype 数组属性,datarows。两者都包含列表,每行一个。

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 有效,因为对象数组包含指针。与列表中的指针一样,它们可以共享。如果做得好,这样的列表可以就地修改。

我通过在lil_matrix 文档上对view 进行页面搜索发现了这一点。对于其他格式,我没有发现任何类似的东西。

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-indexview, something thatndarray` 做不到:

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]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多