我在文本文件中以制表符分隔格式存储矩阵。它密集存储,但我知道它非常稀疏。我想将这个矩阵加载到Python的稀疏格式之一。矩阵非常大,因此执行scipy.loadtxt(...)
然后将生成的密集数组转换为稀疏格式将在中间步骤中占用太多RAM内存,因此这不是一个选项。
答案 0 :(得分:2)
loadtxt
适用于打开的文件,或任何可以为其提供行的迭代文件。
因此,一个选项是打开文件,并在行块上执行loadtxt
。然后将结果数组转换为稀疏数组。将这些稀疏矩阵收集到一个列表中,并使用block
格式将它们组合成一个矩阵。
我没有多少使用block
格式,但我认为它会正确处理此任务。在封面block
下收集每个块的coo
属性(data
,rows
,cols
),将它们加入3个主coo
} attributes。
在封面loadtxt
下,只需读取每一行,将其解析为数组或列表;将所有这些行收集到一个列表中,最后将该嵌套列表传递给np.array()
。
因此,您可以读取每一行,将其解析为列表或值数组,查找非零值,并汇编相关的coo
数组。
通常通过汇编data
,i
,j
1d数组,然后调用coo_matrix((data,(i,j)),...)
来创建大型稀疏矩阵。您需要使用此CSV数据的方式之一。
这是一个逐行的方法,相当于在1行块上使用loadtxt
:
测试文本列表,相当于文件:
In [840]: txt=b"""1,0,0,2,3
0,0,0,0,0
4,0,0,0,0
0,0,0,3,0
""".splitlines()
In [841]:
In [841]: np.loadtxt(txt,delimiter=',',dtype=int)
Out[841]:
array([[1, 0, 0, 2, 3],
[0, 0, 0, 0, 0],
[4, 0, 0, 0, 0],
[0, 0, 0, 3, 0]])
逐行处理
In [842]: ll=[]
In [843]: for line in txt:
ll.append(np.loadtxt([line],delimiter=','))
.....:
In [844]: ll
Out[844]:
[array([ 1., 0., 0., 2., 3.]),
array([ 0., 0., 0., 0., 0.]),
array([ 4., 0., 0., 0., 0.]),
array([ 0., 0., 0., 3., 0.])]
现在将每个数组转换为coo
矩阵:
In [845]: lc=[[sparse.coo_matrix(l)] for l in ll]
In [846]: lc
Out[846]:
[[<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in COOrdinate format>],
[<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 0 stored elements in COOrdinate format>],
[<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>],
[<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in COOrdinate format>]]
并使用bmat
汇总列表(bsr_matrix
的'封面'):
In [847]: B=sparse.bmat(lc)
In [848]: B
Out[848]:
<4x5 sparse matrix of type '<class 'numpy.float64'>'
with 5 stored elements in COOrdinate format>
In [849]: B.A
Out[849]:
array([[ 1., 0., 0., 2., 3.],
[ 0., 0., 0., 0., 0.],
[ 4., 0., 0., 0., 0.],
[ 0., 0., 0., 3., 0.]])
sparse.coo_matrix(l)
只是将每行压缩为bmat
兼容对象的简单方法。
以2行方式处理文本:
In [874]: ld=[]
In [875]: for i in range(0,4,2):
arr = np.loadtxt(txt[i:i+2],delimiter=',')
ld.append([sparse.coo_matrix(arr)])
.....:
In [876]: ld
Out[876]:
[[<2x5 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in COOrdinate format>],
[<2x5 sparse matrix of type '<class 'numpy.float64'>'
with 2 stored elements in COOrdinate format>]]
就像之前一样提供sparse.bmat
。