2017-04-25 78 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