直接将scipy.sparse矩阵保存为常规txt文件

2 投票
1 回答
51 浏览
提问于 2025-04-12 09:01

我有一个 scipy.sparse 矩阵(也就是 csr_matrix())。但是我想把它保存到一个文件里,不想用 .npz 格式,而是想用普通的 .txt.csv 文件。我的问题是,我的内存不够,无法把这个稀疏矩阵转换成普通的 np.array() 然后再保存到文件里。有没有办法可以在内存中保持稀疏矩阵的状态,但直接把它保存成普通矩阵的形式:

0 0 0
0 1 0
1 0 1

到磁盘上?或者有没有办法在不把 .npz 文件加载到内存中的情况下“解压”它?(就像在 Bash 中用 gunzip 或 unzip 一样)。

1 个回答

2

对新问题的回答:

import numpy as np
from scipy import sparse, io
A = sparse.eye(5, format='csr') * np.pi
np.set_printoptions(precision=16, linewidth=1000)
with open('matrix.txt', 'a') as f:
    for row in A:
        f.write(str(row.toarray()[0]))
        f.write('\n')

# [3.141592653589793 0.                0.                0.                0.               ]
# [0.                3.141592653589793 0.                0.                0.               ]
# [0.                0.                3.141592653589793 0.                0.               ]
# [0.                0.                0.                3.141592653589793 0.               ]
# [0.                0.                0.                0.                3.141592653589793]

还有带开始/结束括号的情况:

import numpy as np
from scipy import sparse, io
A = sparse.eye(5, format='csr') * np.pi
np.set_printoptions(precision=16, linewidth=1000)
with open('matrix.txt', 'a') as f:
    for i, row in enumerate(A):
        f.write('[' if (i == 0) else ' ')
        f.write(str(row.toarray()[0]))
        f.write(']' if (i == A.shape[0] - 1) else '\n')

# [[3.141592653589793 0.                0.                0.                0.               ]
#  [0.                3.141592653589793 0.                0.                0.               ]
#  [0.                0.                3.141592653589793 0.                0.               ]
#  [0.                0.                0.                3.141592653589793 0.               ]
#  [0.                0.                0.                0.                3.141592653589793]]

根据你的数据,你可能需要调整一下 set_printoptions


对原始问题的回答,这个问题并不要求矩阵以稠密格式写出。

Harwell-Boeing格式是纯文本格式:

import numpy as np
from scipy import sparse, io
A = sparse.eye(3, format='csr') * np.pi

# Default title                                                           0       
#              3             1             1             1
# RUA                        3             3             3             0
# (40I2)          (40I2)          (3E25.16)           
#  1 2 3 4
#  1 2 3
#   3.1415926535897931E+00  3.1415926535897931E+00  3.1415926535897931E+00

io.hb_write('matrix.txt', A)  # saves as matrix.txt
A2 = io.hb_read('matrix.txt')
assert not (A2 != A).nnz  # efficient check for equality

Matrix Market也是:

io.mmwrite('matrix', A)  # saves as matrix.mtx

# %%MatrixMarket matrix coordinate real symmetric
# %
# 3 3 3
# 1 1 3.141592653589793e+00
# 2 2 3.141592653589793e+00
# 3 3 3.141592653589793e+00

A2 = io.mmread('matrix')
assert not (A2 != A).nnz

如果你想要一个更简单的格式,虽然这需要更多的代码:

import numpy as np
from scipy import sparse
A = sparse.eye(10, format='csr')*np.pi

np.savetxt('data.txt', A.data)
np.savetxt('indices.txt', A.indices, fmt='%i')
np.savetxt('indptr.txt', A.indptr, fmt='%i')

加载时:

data = np.loadtxt('data.txt')
indices = np.loadtxt('indices.txt', dtype=np.int32)
indptr = np.loadtxt('indptr.txt', dtype=np.int32)

A2 = sparse.csr_matrix((data, indices, indptr))
assert not (A2 != A).nnz

但重要的是,你只需要保存 csr_matrixdataindicesindptr 属性。

撰写回答