2013-11-02 229 views
1

我有一個矩陣A在CSC-格式,這是我索引只是一個單一的柱SciPy的:稀疏矩陣來ndarray

b = A[:,col] 

導致(N×1)矩陣的。我想要做的是:

v = M * b 

其中M是CSR中的(n×n)矩陣。結果v是(n×1)CSR矩陣。我需要迭代v中的值(實際上不包括0)並檢索滿足特定條件的元素的索引(注意:稀疏矩陣格式未被選擇以適合該特定操作,但是一般矩陣x矩陣產品應該是最快與CSR * CSC,對不對?)

問題是,迭代在CSR格式化向量(0 <我< n:v [i,0])的條目是非常慢,我真的浪費相當一些記憶因爲v不再稀疏了。

任何人都可以告訴我如何執行這些操作,我可以快速迭代結果向量,保持複製相關的內存開銷很小?

IN: M (CSR-Matrix), A (CSC-Matrix), col_index 
v = M * A[:,col_index] 
for entries in v: 
    do stuff 

是否有可能以某種方式加快CSC矩陣中列的「高級」索引?在代碼中的其他位置,我必須提取A的子矩陣(不能重新配置以允許切片,因此使用索引數組),其中包括所有列的給定子集。在線分析時,[:,idxlist]需要相當長的時間。

期待您的建議

回答

1

的SciPy的稀疏模塊越來越好每一個版本,但很明顯工作正在進行中,所以有大量的優化,你可以通過直接訪問對象的內臟做的。例如。你的情況:

>>> a = sps.rand(5, 20, density=0.2, format='csr') 
>>> b = sps.rand(20, 1, density=0.2, format='csc') 
>>> c = a * b 
>>> c.A 
array([[ 0.30331594], 
     [ 0.  ], 
     [ 0.12198742], 
     [ 0.34350077], 
     [ 0.  ]]) 

你可以得到的c非零條目c.data

>>> c.data 
array([ 0.30331594, 0.12198742, 0.34350077]) 

獲得相應的行數是有點麻煩。也許最簡單的將是你的輸出到CSC格式轉換,因爲他們,你讓他們直接爲c.indicesc.data仍然會像以前一樣:

>>> c.tocsc().indices 
array([0, 2, 3]) 
>>> c.tocsc().data 
array([ 0.30331594, 0.12198742, 0.34350077]) 

但是你可以提取它們不,如果你做轉換不喜歡它:

>>> np.where(c.indptr[:-1] != c.indptr[1:])[0] 
array([0, 2, 3], dtype=int64) 

所以,如果你想找到,例如最大的價值和它的行數,你可以這樣做:

>>> row_idx = np.where(c.indptr[:-1] != c.indptr[1:])[0] 
>>> idx = np.argmax(c.data) 
>>> c.data[idx], row_idx[idx] 
(0.34350077450601624, 3) 
+0

謝謝。現在我最終把M變成了一個CSC矩陣。由於轉換(CSC * CSC矩陣mult而不是CSR * CSC),具有相當大的矩陣的基準測試並未真正顯示代碼的任何特定放緩。 但是,作爲一個很好的副作用,我立即得到了索引數組中的所有非零索引,就像你說的:) – limbonic

1

在代碼審查的問題,我正在探索加快了稀疏矩陣的行迭代的方式,https://codereview.stackexchange.com/questions/32664/numpy-scipy-optimization/33566#33566

csrgetrow是出奇慢。至少對於那個小的測試用例來說,將稀疏矩陣轉換爲密集數組會更快,並且使用常規的numpy索引(使用np.nonzero來獲得稀疏條目)。將矩陣轉換爲lil同樣快,並在zip(X.data, X.rows)上執行常規Python迭代。

我的印象是,scipy.sparse最適合線性代數問題,並且對索引和迭代速度較慢。