【问题标题】:Read a dense matrix from a file directly into a sparse numpy array?将文件中的密集矩阵直接读取到稀疏的numpy数组中?
【发布时间】:2016-06-16 21:38:59
【问题描述】:

我有一个以制表符分隔格式存储在文本文件中的矩阵。它存储密集,但我知道它非常稀疏。我想将此矩阵加载到 Python 的一种稀疏格式中。该矩阵非常大,因此执行 scipy.loadtxt(...) 然后将生成的密集数组转换为稀疏格式会在中间步骤中占用过多的 RAM 内存,因此这不是一个选项。

【问题讨论】:

  • 您可能会自己编写。首先,逐行读取 csv 并收集稀疏输入 - I、j、非零值数据。

标签: python arrays numpy matrix scipy


【解决方案1】:

loadtxt 适用于打开的文件,或任何为其提供行的可迭代对象。

因此,一种选择是打开文件,并在行块上执行loadtxt。然后将生成的数组转换为稀疏数组。将这些稀疏矩阵收集到一个列表中,并使用block 格式将它们组装成一个矩阵。

我没有太多使用block 格式,但我认为它可以正确处理此任务。封面下block收集每个块的coo属性(datarowscols),将它们连接成3个主coo属性。

在封面下loadtxt 只是读取每一行,将其解析为数组或列表;将所有这些行收集到一个列表中,最后将该嵌套列表传递给np.array()

因此您可以读取每一行,将其解析为值列表或数组,找到非零值,然后组装相关的coo 数组。

大型稀疏矩阵通常通过组合dataij 一维数组,然后调用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

【讨论】:

    猜你喜欢
    • 2020-11-27
    • 2012-02-20
    • 2013-05-06
    • 1970-01-01
    • 2016-06-25
    • 2013-11-05
    • 2019-09-02
    • 1970-01-01
    • 2021-02-23
    相关资源
    最近更新 更多