2017-02-07 57 views
0

物化稀疏矩陣我在.npy格式保存到磁盤3個NumPy的陣列,一起共計約40 GB(從一個非常大的文件組表示文本計數數據)。三個陣列表示scipy.sparse.csc_matrix稀疏矩陣的dataindices,並indptr屬性。使用gensim Scipy2Corpus而不在存儲器

我想對這些數據使用分佈式gensim LsiModel,具體來說就是使用gensim.matutils.Scipy2Corpus函數從底層稀疏矩陣中提供語料庫迭代器。

不過,我不希望兌現在內存中的整個矩陣。相反,我怎麼能告訴gensim關於底層磁盤數據,並從磁盤具有gensim流進CSC矩陣根據需要塊分配給工作進程?如果我理解正確的話,這就是Scipy2Corpusdistributed LsiModel examples要求做,而是他們需要具體化陣列爲提前一個CSC矩陣。

我已經嘗試了加載每個底層數組與mmap_mode='r',但構造物化csc矩陣的功能,scipy.sparse.csc_matrix將拉動所有的數據在不管。

+0

你對「csr」格式有多瞭解?描述這個流應該做什麼。按行(或按列)發送數組?或發送2d塊。 – hpaulj

+0

底層數據採用csc格式,而不是csr。每個列是一個術語,行(非常稀疏的術語計數向量)對應於文檔。 [Gensim將轉換爲csr](https://github.com/RaRe-Technologies/gensim/blob/develop/gensim/matutils.py#L167),因此需要csc輸入。流效應是提供大塊的行,而不需要實現整個稀疏矩陣對象。 – ely

+0

你需要做的是構造一些稀疏矩陣,並執行各種轉換(對csc等),索引(1或多行或列)並跟蹤數據,索引和indptr屬性。我會檢查他們的'id'和他們的數據指針('.__ array_interface __ ['data']')。這個想法是追蹤何時製作副本,何時只是一個視圖。一個視圖有使用'mmap'的機會,一個副本幾乎肯定會加載整個事情。 – hpaulj

回答

0

我做了一個稀疏矩陣:

In [207]: A=sparse.random(100,100,.1,'csr') 
In [208]: A 
Out[208]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>' 
    with 1000 stored elements in Compressed Sparse Row format> 
其屬性

製作的複製品,並將其保存

In [209]: D,I,J = A.data.copy(),A.indptr.copy(),A.indices.copy() 
In [236]: np.save('sparse_d',D) 
In [237]: np.save('sparse_I',I) 
In [238]: np.save('sparse_J',J) 

如果我重新加載它們爲mmap,我可以做一個新的矩陣:

In [240]: D1=np.load('sparse_d.npy', mmap_mode='r') 
In [241]: I1=np.load('sparse_I.npy', mmap_mode='r') 
In [242]: J1=np.load('sparse_J.npy', mmap_mode='r') 
In [243]: Amm=sparse.csr_matrix((D1,J1,I1),A.shape) 

但這個新陣列的屬性中的文件的內存拷貝:

In [246]: type(D1) 
Out[246]: numpy.core.memmap.memmap 
In [247]: type(Amm.data) 
Out[247]: numpy.ndarray 

因此,由mmap數組構成的稀疏矩陣加載所有數據(如原始帖子中所聲明的)。

In [252]: A.indptr 
Out[252]: 
array([ 0, 10, 20, 29, 36, 46, 60, 66, 74, 85, 93, 
     104, 117, 128, 139, 147, 156, 165, 172, 188, 201, 211, ... 

我能得到的A片與

In [254]: A37=A[3:7,:] 
In [255]: A37 
Out[255]: 
<4x100 sparse matrix of type '<class 'numpy.float64'>' 
    with 37 stored elements in Compressed Sparse Row format> 

這是A副本,而不是一個視圖(因爲它會一直爲密集排列)。

爲這些行中的相關值indptr

In [256]: I1[3:8] 
Out[256]: memmap([29, 36, 46, 60, 66]) 

66-29是37,非零值的A37數量。

我可以從mmap陣列切片作出的稀疏矩陣:

In [259]: Amm37=sparse.csr_matrix((D1[29:66],J1[29:66],I1[3:8]-I1[3]), shape=(4, 100)) 
In [260]: Amm37 
Out[260]: 
<4x100 sparse matrix of type '<class 'numpy.float64'>' 
    with 37 stored elements in Compressed Sparse Row format> 
In [261]: np.allclose(A37.A, Amm37.A) 
Out[261]: True 

雖然Amm37的屬性是在存儲器中,所述D1J1函數的輸入是mmap切片:

In [262]: D1[29:66] 
Out[262]: 
memmap([ 0.08874032, 0.18952295, 0.43034343, 0.83725733, 0.61073925, 
     0.9178207 , 0.03644072, 0.32206696, 0.90945298, 0.20585155, 
     .... 0.43905333]) 
In [263]: I1[3:8]-I1[3] 
Out[263]: array([ 0, 7, 17, 31, 37]) 

所以是的,我可以從保存的屬性中重新創建一個原始A的行切片,而無需加載整個mmap數組。我需要的是從3個陣列中選擇的切片。同樣,我可以從csc格式數組中選擇列。

但是,從csr屬性中拉出一列而不完全加載它們將非常困難。所需的dataindices值將分散在存儲的陣列中。將csr屬性轉換爲csc需要創建完整的csr矩陣並使用其tocsc()方法。

+0

我面臨的問題是我開始使用的數據格式是csc格式,而不是csr,即使相關的迭代維度是行(文檔)。 csc矩陣來自某些需要快速遍歷列(術語)的不同應用程序。但要應用LSA來提高同一應用程序的性能,它將需要從定義csc矩陣的mmap文件開始,並在其上迭代* row-wise *,儘管它是csc。 – ely

相關問題