2013-01-23 31 views
3

矩陣的有效切片我想重塑2D scipy.sparse.csr.csr_matrix(讓我們這A調用)到2D numpy.ndarray(我們稱之爲B)。使用矩陣乘法,與Python,NumPy的,SciPy的

A可能是

>shape(A) 
(90, 10) 

然後 B應該

>shape(B) 
(9,10) 

其中每10行的A將在一個新的新的價值,即最大窗口和列進行塑形。列運算符不處理這種不可稀疏矩陣的類型。如何通過矩陣乘法得到B

+4

我不覺得矩陣乘法做的是對的選擇**最大**,可能是**總和**。你有沒有考慮使用CSC格式,而不是支持列切片? – Jaime

+0

我想不出一種在稀疏數組上快速執行此操作的方法。但是,即使一個'(9000,1000)'陣列可在我的系統中處理約'100個ms'做'行,COLS = sparse_mat.shape'然後'np.max(sparse_mat.toarray()。重塑(行//10,10,cols),axis = 1)'。 – Jaime

+0

感謝您的意見,在我的情況下,它需要幾秒鐘,因爲矩陣要大得多。但是我將一些先前的知識放入,你沒有:行數超過列的數量,因此我將循環遍歷cols,重新塑形並計算最大值。這不是我想要的,但似乎沒有什麼更快。 –

回答

1

使用矩陣乘法,你可以做帶高效切片創建與那些在正確的地方「切片」矩陣。切片矩陣與「切片器」具有相同的type,因此您可以高效地控制輸出類型。

下面你將看到一些比較和最有效的爲您的情況是索要.A矩陣和切它。它顯示出比.toarray()方法快得多。使用乘法是第二快的選項時,「限幅器」作爲ndarray,乘以csr矩陣創建並切片的結果。

OBS:使用稀疏矩陣Acoo導致稍慢定時,保持相同的比例,以及sol3是不適用的,我後來意識到的是,在乘法它被自動轉換爲csr

import scipy 
import scipy.sparse.csr as csr 
test = csr.csr_matrix([ 
[11,12,13,14,15,16,17,18,19], 
[21,22,23,24,25,26,27,28,29], 
[31,32,33,34,35,36,37,38,39], 
[41,42,43,44,45,46,47,48,49], 
[51,52,53,54,55,56,57,58,59], 
[61,62,63,64,65,66,67,68,69], 
[71,72,73,74,75,76,77,78,79], 
[81,82,83,84,85,86,88,88,89], 
[91,92,93,94,95,96,99,98,99]]) 

def sol1(): 
    B = test.A[2:5] 

def sol2(): 
    slicer = scipy.array([[0,0,0,0,0,0,0,0,0], 
          [0,0,0,0,0,0,0,0,0], 
          [0,0,1,0,0,0,0,0,0], 
          [0,0,0,1,0,0,0,0,0], 
          [0,0,0,0,1,0,0,0,0]]) 
    B = (slicer*test)[2:] 
    return B 

def sol3(): 
    B = (test[2:5]).A 
    return B 

def sol4(): 
    slicer = csr.csr_matrix(((1,1,1),((2,3,4),(2,3,4))), shape=(5,9)) 
    B = ((slicer*test).A)[2:] # just changing when we do the slicing 
    return B 

def sol5(): 
    slicer = csr.csr_matrix(((1,1,1),((2,3,4),(2,3,4))), shape=(5,9)) 
    B = ((slicer*test)[2:]).A 
    return B 


timeit sol1() 
#10000 loops, best of 3: 60.4 us per loop 

timeit sol2() 
#10000 loops, best of 3: 91.4 us per loop 

timeit sol3() 
#10000 loops, best of 3: 111 us per loop 

timeit sol4() 
#1000 loops, best of 3: 310 us per loop 

timeit sol5() 
#1000 loops, best of 3: 363 us per loop 

編輯:答案已經更新由.A更換.toarray(),使更快的結果和現在最好的解決方案是放在頂部