我有一个相当大的稀疏矩阵,我认为,在加载到内存中时会占用1Gb。存储和检索大型稀疏矩阵
我不需要随时访问整个矩阵,所以某种内存映射可以工作;但是,使用numpy或辛辣(我熟悉的工具)来记忆映射稀疏矩阵似乎并不可行。
它可以很容易地适应内存,但如果我每次运行该程序时都必须加载它,那将是一件痛苦的事情。也许有一种方法可以在运行之间保持它在内存中?
那么,你有什么建议: 1.找到一种方法来存储映射稀疏矩阵; 2.每次加载整个想法到内存中 3.?
我有一个相当大的稀疏矩阵,我认为,在加载到内存中时会占用1Gb。存储和检索大型稀疏矩阵
我不需要随时访问整个矩阵,所以某种内存映射可以工作;但是,使用numpy或辛辣(我熟悉的工具)来记忆映射稀疏矩阵似乎并不可行。
它可以很容易地适应内存,但如果我每次运行该程序时都必须加载它,那将是一件痛苦的事情。也许有一种方法可以在运行之间保持它在内存中?
那么,你有什么建议: 1.找到一种方法来存储映射稀疏矩阵; 2.每次加载整个想法到内存中 3.?
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
下可能工作作为一个笼统的概念,但你将不得不找出很多细节......你应该首先让自己熟悉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] = 4
和a.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]])
你的矩阵是如何存储的?您想要在存储器中同时加载矩阵的哪些部分?正如问,你的问题是广泛的答案... – Jaime