python - 存储和检索大型稀疏矩阵

标签 python memory matrix numpy sparse-matrix

<分区>

我有一个相当大的稀疏矩阵,我估计它在加载到内存中时会占用 1Gb。

我不需要一直访问整个矩阵,所以某种内存映射会起作用;然而,似乎不可能使用 numpy 或 spicy(我熟悉的工具)来内存映射稀疏矩阵。

它可以很容易地装入内存,但如果我每次运行程序时都必须加载它,那将是一件痛苦的事情。也许有某种方法可以在运行之间将其保存在内存中?

那么,你有什么建议: 1. 找到一种内存映射稀疏矩阵的方法; 2.每次都将整个想法加载到内存中 3. ?

最佳答案

以下内容可能作为一个一般概念,但您将不得不弄清楚很多细节......您应该首先让自己熟悉 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]

因此您可以将这三个数组存储在磁盘中,并以内存映射的形式访问它们,然后您可以按如下方式检索行 m 到 n:

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]])

关于python - 存储和检索大型稀疏矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16039852/

相关文章:

javascript - Python 优于 JavaScript? (请提供事实)

Python——生成器在迭代器之间散布值——我这样做正确吗?

c++ - Xeon 每次内存访问会将多少字节带入缓存?

r - 如何计算R中的邻接矩阵

r - 从矩阵列表中获取元素

python - Dask 相当于 pandas.DataFrame.update

python - 如何测试多个变量与单个值的相等性?

java - Clojure 关键字在内存中的大小是多少?

c - 在指针 C 中保存多个字符(动态内存)

c - 将随机元素分配给函数中的 int 二维矩阵时,如何避免 C 中的 SIGSEGV 段错误?