2013-04-16 33 views
3

我有一個相當大的稀疏矩陣,我認爲,在加載到內存中時會佔用1Gb。存儲和檢索大型稀疏矩陣

我不需要隨時訪問整個矩陣,所以某種內存映射可以工作;但是,使用numpy或辛辣(我熟悉的工具)來記憶映射稀疏矩陣似乎並不可行。

它可以很容易地適應內存,但如果我每次運行該程序時都必須加載它,那將是一件痛苦的事情。也許有一種方法可以在運行之間保持它在內存中?

那麼,你有什麼建議: 1.找到一種方法來存儲映射稀疏矩陣; 2.每次加載整個想法到內存中 3.?

+0

你的矩陣是如何存儲的?您想要在存儲器中同時加載矩陣的哪些部分?正如問,你的問題是廣泛的答案... – Jaime

回答

2

Scipy支持different kinds of sparse matrices。但是你必須編寫一個例程來將它讀入內存。你應該使用哪種類型取決於你想用它做什麼。

如果您的矩陣非常稀疏,您可以使用struct模塊將(row, column, value)元組作爲二進制數據保存到磁盤。假設可移植性不成問題,這將使磁盤上的數據更小並且更容易加載。

然後,您可以讀取的數據是這樣的:

import struct 
from functools import partial 

fmt = 'IId' 
size = struct.calcsize(fmt) 

with open('sparse.dat', 'rb') as infile: 
    f = partial(infile.read, size) 
    for chunk in iter(f, ''): 
     row, col, value = struct.unpack(fmt, chunk) 
     # put it in your matrix here 
5

下可能工作作爲一個籠統的概念,但你將不得不找出很多細節......你應該首先讓自己熟悉CSR format,其中所有信息的數組存儲在3個陣列中,兩個長度的非零項的數量,行的長度的一個數目加一:

>>> import scipy.sparse as sps 
>>> a = sps.rand(10, 10, density=0.05, format='csr') 
>>> a.toarray() 
array([[ 0.  , 0.46531486, 0.03849468, 0.51743202, 0.  ], 
     [ 0.  , 0.67028033, 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.9967058 ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.  ]]) 
>>> a.data 
array([ 0.46531486, 0.03849468, 0.51743202, 0.67028033, 0.9967058 ]) 
>>> a.indices 
array([1, 2, 3, 1, 4]) 
>>> a.indptr 
array([0, 3, 4, 4, 5, 5]) 

所以a.data具有非零行,按行主要順序,a.indices具有非零零表項的相應列索引,並且a.indptr具有起始索引到其中每行的數據開始的另外兩個陣列,例如, a.indptr[3] = 4a.indptr[3+1] = 5,因此第四行的非零項爲a.data[4:5],列索引爲a.indices[4:5]

所以,你可以存儲在磁盤這三個陣列,並訪問他們作爲memmaps,然後你可以檢索行通過爲N×M如下:

ip = indptr[m:n+1].copy() 
d = data[ip[0]:ip[-1]] 
i = indices[ip[0]:ip[-1]] 
ip -= ip[0] 
rows = sps.csr_matrix((d, i, ip)) 

作爲概念的一般證明:

>>> c = sps.rand(1000, 10, density=0.5, format='csr') 
>>> ip = c.indptr[20:25+1].copy() 
>>> d = c.data[ip[0]:ip[-1]] 
>>> i = c.indices[ip[0]:ip[-1]] 
>>> ip -= ip[0] 
>>> rows = sps.csr_matrix((d, i, ip)) 
>>> rows.toarray() 
array([[ 0.  , 0.  , 0.  , 0.  , 0.55683501, 
     0.61426248, 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.67789204, 0.  , 0.71821363, 
     0.01409666, 0.  , 0.  , 0.58965142, 0.  ], 
     [ 0.  , 0.  , 0.  , 0.1575835 , 0.08172986, 
     0.41741147, 0.72044269, 0.  , 0.72148343, 0.  ], 
     [ 0.  , 0.73040998, 0.81507086, 0.13405909, 0.  , 
     0.  , 0.82930945, 0.71799358, 0.8813616 , 0.51874795], 
     [ 0.43353831, 0.00658204, 0.  , 0.  , 0.  , 
     0.10863725, 0.  , 0.  , 0.  , 0.57231074]]) 
>>> c[20:25].toarray() 
array([[ 0.  , 0.  , 0.  , 0.  , 0.55683501, 
     0.61426248, 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.67789204, 0.  , 0.71821363, 
     0.01409666, 0.  , 0.  , 0.58965142, 0.  ], 
     [ 0.  , 0.  , 0.  , 0.1575835 , 0.08172986, 
     0.41741147, 0.72044269, 0.  , 0.72148343, 0.  ], 
     [ 0.  , 0.73040998, 0.81507086, 0.13405909, 0.  , 
     0.  , 0.82930945, 0.71799358, 0.8813616 , 0.51874795], 
     [ 0.43353831, 0.00658204, 0.  , 0.  , 0.  , 
     0.10863725, 0.  , 0.  , 0.  , 0.57231074]])