如何保存和加载scipy稀疏csr矩阵的字典?

时间:2017-12-04 02:55:23

标签: python scipy

我有dictscipy.sparse.csr_matrix个对象作为值,带有整数键。如何将其保存在单独的文件中?

如果我为每个条目定期ndarray,那么我可以使用json对其进行序列化,但是当我尝试使用稀疏矩阵时:

    with open('filename.txt', 'w') as f:
            f.write(json.dumps(the_matrix))

我得到一个TypeError:

TypeError: <75x75 sparse matrix of type '<type 'numpy.int64'>' with 10 stored elements in Compressed Sparse Row format> is not JSON serializable

如何使用作为稀疏csr矩阵的整数和值来保存字典?

3 个答案:

答案 0 :(得分:0)

较新的scipy版本具有scipy.sparse.save_npz函数(以及相应的加载)。它将稀疏矩阵的属性保存到numpy savez zip存档。在csr的情况下,会保存dataindicesindptr数组以及形状。

scipy.io.savemat可以以MATLAB兼容格式(csc)保存稀疏矩阵。有一种或两种其他scipy.io格式可以处理稀疏矩阵,但我没有使用过它们。

虽然稀疏矩阵包含numpy数组,但它不是数组的子类,因此numpy函数不能直接使用。

numpy数组的pickle方法是np.save。包含对象的数组使用pickle(如果可能)。因此,数组字典的泡菜应该有效。

稀疏dok格式是dict的子类,因此可能是pickleable。它甚至可以与json一起使用。但我还没试过。

顺便说一句,普通的numpy数组也不能是jsoned

In [427]: json.dumps(np.arange(5))
TypeError: array([0, 1, 2, 3, 4]) is not JSON serializable
In [428]: json.dumps(np.arange(5).tolist())
Out[428]: '[0, 1, 2, 3, 4]'

dok也不起作用。键是索引的元组,

In [433]: json.dumps(M.todok())
TypeError: keys must be a string

MatrixMarket是一种处理稀疏的文本格式:

In [444]: io.mmwrite('test.mm', M)   
In [446]: cat test.mm.mtx
%%MatrixMarket matrix coordinate integer general
%
1 5 4
1 2 1
1 3 2
1 4 3
1 5 4

答案 1 :(得分:0)

import numpy as np
from scipy.sparse import lil_matrix, csr_matrix, issparse
import re
def save_sparse_csr(filename, **kwargs):
    arg_dict = dict()
    for key, value in kwargs.items():
        if issparse(value):
            value = value.tocsr()
            arg_dict[key+'_data'] = value.data
            arg_dict[key+'_indices'] = value.indices
            arg_dict[key+'_indptr'] = value.indptr
            arg_dict[key+'_shape'] = value.shape
        else:
            arg_dict[key] = value

    np.savez(filename, **arg_dict)

def load_sparse_csr(filename):
    loader = np.load(filename)
    new_d = dict()
    finished_sparse_list = []
    sparse_postfix = ['_data', '_indices', '_indptr', '_shape']

    for key, value in loader.items():
        IS_SPARSE = False
        for postfix in sparse_postfix:
            if key.endswith(postfix):
                IS_SPARSE = True
                key_original = re.match('(.*)'+postfix, key).group(1)
                if key_original not in finished_sparse_list:
                    value_original = csr_matrix((loader[key_original+'_data'], loader[key_original+'_indices'], loader[key_original+'_indptr']),
                                      shape=loader[key_original+'_shape'])
                    new_d[key_original] = value_original.tolil()
                    finished_sparse_list.append(key_original)
                break

        if not IS_SPARSE:
            new_d[key] = value

    return new_d

您可以编写如上所示的包装器。

答案 2 :(得分:0)

我在尝试保存值为csr_matrix的字典时遇到了同样的问题。使用泡菜将其倾倒到磁盘上。文件处理程序应以“ wb”模式打开。

import pickle
pickle.dump(csr_dict_obj, open("csr_dict.pkl","wb"))

使用重新加载字典。

csr_dict = pickle.load(open("csr_dict.pkl","rb"))