2017-04-25 40 views
1

我有一个稀疏矩阵的行信息的Python列表。每行都被表示为(列,值)元组列表。说它alist从元组列表构造稀疏的lil_matrix

alist = [[(1,10), (3,-3)], 
     [(2,12)]] 

我怎样才能有效地从列表此列表构造SciPy的稀疏矩阵,造成这样的矩阵:

0 10 0 -3 
0 0 2 0 

最明显的方法是使scipy.sparse.lil_matrix,这内部有这个“列表清单”结构。但是从scipy.sparse.lil_matrix — SciPy v0.19.0 Reference Guide我看到构建他们的只有三个途径:

  • 从密集阵列
  • 开始从另一个稀疏线阵开始
  • 只是构建一个空数组

所以唯一的办法得到新的数据要么是用其他稀疏矩阵表示来解决这个问题,要么是从一个密集的数组开始,这两个都不能解决最初的问题,并且这两个似乎都可能比lil_matrix本身为这个数据。

我想我可以做一个空的,并使用循环来增加值,但肯定我失去了一些东西。

当谈到稀疏矩阵时,scipy文档确实令人沮丧。

回答

1

您的数据布局是不寻常的。这是我第一次使用它。

In [565]: M = sparse.lil_matrix((2,4), dtype=int) 
In [566]: M 
Out[566]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 0 stored elements in LInked List format> 
In [567]: for i,row in enumerate(alist): 
    ...:  for col in row: 
    ...:   M[i, col[0]] = col[1] 
    ...:   
In [568]: M 
Out[568]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 3 stored elements in LInked List format> 
In [569]: M.A 
Out[569]: 
array([[ 0, 10, 0, -3], 
     [ 0, 0, 12, 0]]) 

是的,它是迭代的;而lil是此目的的最佳格式。

或者使用普通coo风格的输入:

In [580]: data,col,row = [],[],[] 
In [581]: for i, rr in enumerate(alist): 
    ...:  for cc in rr: 
    ...:   row.append(i) 
    ...:   col.append(cc[0]) 
    ...:   data.append(cc[1]) 
    ...:   
In [582]: data,col,row 
Out[582]: ([10, -3, 12], [1, 3, 2], [0, 0, 1]) 
In [583]: M1=sparse.coo_matrix((data,(row,col)),shape=(2,4)) 
In [584]: M1 
Out[584]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 3 stored elements in COOrdinate format> 
In [585]: M1.A 
Out[585]: 
array([[ 0, 10, 0, -3], 
     [ 0, 0, 12, 0]]) 

另一种选择是创建空白lil矩阵,并直接在其属性填写:

换句话说,有开始:

In [591]: m.data 
Out[591]: array([[], []], dtype=object) 
In [592]: m.rows 
Out[592]: array([[], []], dtype=object) 

并将它们更改为:

In [587]: M.data 
Out[587]: array([[10, -3], [12]], dtype=object) 
In [588]: M.rows 
Out[588]: array([[1, 3], [2]], dtype=object) 

它仍然需要在您的alist结构上进行2级迭代。

In [593]: for i, rr in enumerate(alist): 
    ...:  for cc in rr: 
    ...:   m.rows[i].append(cc[0]) 
    ...:   m.data[i].append(cc[1])  
In [594]: m 
Out[594]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 3 stored elements in LInked List format> 
In [595]: m.A 
Out[595]: 
array([[ 0, 10, 0, -3], 
     [ 0, 0, 12, 0]]) 

在另一个评论,你在了解csrindptr提到的困难。最简单的方法是将这些格式转换成一个:

In [597]: Mr=M.tocsr() 
In [598]: Mr.indptr 
Out[598]: array([0, 2, 3], dtype=int32) 
In [599]: Mr.data 
Out[599]: array([10, -3, 12]) 
In [600]: Mr.indices 
Out[600]: array([1, 3, 2], dtype=int32) 
+0

这样一个清晰,有用,详细的答案 - 谢谢!基于COO格式的构造函数看起来很自然,我可以想出一些生成器来生成它,并实现一个内存和时间效率高的输入流水线。我希望scipy的人们以这样的方式添加一些人们会找到它们的例子。这是我的数据进来的格式,并且如[稀疏数组 - 维基百科](https://en.wikipedia.org/wiki/Sparse_array)中所述,考虑到支持所有这些不同稀疏格式的系统数量, d认为更多的人会使用它们交换数据。 – nealmcb

+1

我首先在MATLAB中使用稀疏矩阵来处理有限元问题。有'coo'风格的输入是唯一的选择,尽管它在内部将数据存储为'csc'(至少它是将其保存到'.mat'文件的格式)。大部分稀疏数学都是为线性代数问题而开发的。 'scipy'增加了许多格式(请注意Wiki文章中的链接)。现在大部分稀疏矩阵兴趣来自大数据问题,稀疏特征矩阵,机器学习,语言学等等。例如'scikit learn'增加了一些自己编写的稀疏矩阵工具。 – hpaulj