scipy 使用Python批量阅读和处理大型稀疏矩阵

zbdgwd5y  于 2023-05-29  发布在  Python
关注(0)|答案(1)|浏览(151)

我有一个大型稀疏矩阵存储在一个文件中,由于内存限制,我需要批量处理它。我正在寻找一种有效的方法来读取和处理稀疏矩阵的连续部分,而无需立即将整个文件加载到内存中。
我尝试使用Python中的scipy.sparse模块来处理稀疏矩阵。但是,可用的函数(如scipy.sparse.load_npz())将整个矩阵加载到内存中,这对我的情况来说是不可行的。
下面是我当前代码的一个例子:

class SparseDataLoader:
    def __init__(self, file_name, batch_size, image_width, image_height):
        self.sparse_matrix = sc.sparse.load_npz(file_name)
        self.batch_size = batch_size
        self.image_width = image_width
        self.image_height = image_height
        self.num_batches = self.sparse_matrix.shape[0] // batch_size

    def __iter__(self):
        for batch_index in range(self.num_batches):
            start_index = batch_index * self.image_width * self.batch_size
            end_index = (batch_index + 1) * self.image_width * self.batch_size

            rows_to_extract = np.arange(start_index, end_index)
            batch_sparse_matrix = self.sparse_matrix[rows_to_extract, :]

            batch_dense_matrix = batch_sparse_matrix.toarray()
            batch_images = batch_dense_matrix.reshape(self.batch_size, self.image_width, self.image_height, 1)
            batch_images = np.transpose(batch_images, (0, 2, 1, 3))
            yield batch_images

有没有办法修改这段代码,使其一次只读取和处理稀疏矩阵的一部分?我想加载矩阵的连续部分,创建密集矩阵的批次,并避免将整个文件加载到内存中。
我已经研究了scipy.sparse模块,但我找不到允许阅读特定行或部分加载矩阵的函数。有没有更有效的方法或不同的库可以处理这种情况?
任何关于如何有效地批量读取和处理大型稀疏矩阵的建议或指导都将非常感谢。谢谢你!
下面是我创建数据集的问题的链接:如何在Python中从稀疏2D矩阵创建预定义大小的小批量?

mpgws1up

mpgws1up1#

我记得我曾帮助解决过一个关于批量处理CSC矩阵的类似问题。所以我查了你的历史等等。你应该在问题中提供这种联系,而不是依赖于我的记忆。
查看save_npzload_npz的代码。这只是使用np.savez函数将矩阵的关键属性写入文件。对于CSC,这意味着zip存档有4个文件- shape,data,indices,indptr。在加载时,它获取这些数组,然后直接创建矩阵:

M = sparse.csc_matrix((data, indices, indptr), shape)

然后,您可以按照上一个问题中的方法进行批处理。
所以save/load_npz只使用现有的sparse和numpy函数。没有添加“批处理”或部分加载工具。
有人问过npy数组的部分加载,但我认为没有人提出一个好的方法。这不是不可能的,但你必须知道npy是如何存储的。
在这种情况下,您可以直接打开npz归档文件,并自己加载4个数组,并跳过'make csc'步骤。显然,在indptr中定义“列”边界之前,您无法对数据/索引数组执行任何有意义的操作。
简而言之,您必须了解很多关于np.savez/load的知识,才能绕过sparse.load_npz步骤。

相关问题