Python:序列化/反序列化大量数据

2024-06-17 11:56:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个(非常大的)数据集。大约250000个二进制向量,每个向量的大小为800。
数据集驻留在一个(.txt ascii编码)文件中,位于“压缩表示”中。也就是说,该文件中的每一行表示向量的外观,而不是800个字符的零和一。
例如,假设该文件中的第i行如下所示:

12 14 16 33 93 123 456 133

这意味着第i个向量是第12个、第14个、第16个。。。第133个指数的值为1,其余为0。你知道吗

文件大小略大于30MB。你知道吗

现在,由于我使用这些数据来输入神经网络,因此这些数据需要一些预处理,以便将其转换为网络所期望的:大小为250000的列表,其中该列表中的每个元素都是一个由0和1组成的20x40矩阵(列表列表)。
例如,如果我们将问题重缩放到4x2,则最终列表如下所示:

[[[1,0],[1,1],[0,0],[1,0]], [[0,0],[0,1],[1,0],[1,0]], ..., [[1,1],[0,1],[0,0],[1,1]]]

(只有20x40矩阵代替了4x2矩阵)。你知道吗

所以我写了两个函数:load_data()-它解析文件并返回800个二进制列表的列表,和reshape()-它将列表重塑为20x40个矩阵。
不用说,当load_data()reshape()运行时,我那可怜的笔记本电脑真的很难工作。完成预处理大约需要7-9分钟,而在这段时间里,我可以在笔记本电脑里做任何事情。即使最小化IDE窗口也是一项极其困难的任务。
由于我使用这些数据来调整神经网络,我发现自己经常终止正在运行的进程,重新调整网络,然后重新开始—每次重新启动都会导致对load_data()的调用,然后是reshape()
因此,我决定缩短加载数据的痛苦过程——转换为二进制向量——重塑数据。
我想从文件中加载数据,转换为二进制向量,重塑它的形状并将其序列化为文件my_input
现在,每当我需要向网络提供数据时,我就可以对my_input中的数据进行反序列化,从而节省大量时间。
我就是这样做的:

input_file=open('my_input', 'wb')

print 'loading data from file...'
input_data=load_data()  # this will load the data from file and will re-encode it to binary vectors

print 'reshaping...'
reshaped_input=reshape(input_data)

print 'writing to file...'
cPickle.dump(reshaped_input, input_file, HIGHEST_PROTOCOL)
input_file.close()

问题是:
结果文件是巨大的;1.7GB的大小,似乎游戏不值得蜡烛(我希望我使用它的权利),因为它需要太多的时间来加载它(没有衡量多少,我只是试图加载,9-10分钟后,我放弃了,并杀死了进程)。你知道吗

为什么生成的文件比原始文件大这么多(我希望它会更大,但不会那么大)?
有没有另一种方法来编码数据(序列化/反序列化),这将导致一个较小的文件,并将值得我的时间?
或者,如果有人能提出一个更好的加速方法(除了买一台更快的电脑),那也太好了。你知道吗

另外,我不关心反序列化时的兼容性问题。唯一可以反序列化这些数据的地方是在我的计算机上。你知道吗


Tags: 文件数据网络列表inputdata序列化my
1条回答
网友
1楼 · 发布于 2024-06-17 11:56:36

如果要为数据中的每个值存储一位,那么最终会得到一个25MB的文件;因此,您的“压缩”方案实际上会使文件变大。当前方案的唯一优点是可以将数据存储在ascii中。你知道吗

计算:

250.000 * 800 bits = 250.000 * 100 bytes = 25.000.000 bytes = 25 MB

所以只需手动存储位模式,将它们读回并继续计算。你知道吗

编辑:看起来阻力最小的路径是使用第三方模块^{}(即您需要下载它)。您必须首先将长的矩阵列表动态地展平为一个平面列表(作为迭代器),将其写成一个位序列(注意:每个32位int可以用32个值“打包”,而不是像您在注释中建议的那样只有一个值),然后对输入进行反向转换。列表平坦化的方法非常简单(请参见here中的选择),但这里有一个补充的非平坦化代码。你知道吗

from itertools import zip_longest    
def chunks(iterable, size):
    "chunks(3, 'abcdefg', 'x')  > ('a','b','c'), ('d','e','f'), ('g', 0, 0)"
    return zip_longest(*[iter(iterable)]*size, fillvalue=0)

def flatten(data):
    """Convert a list of N x M matrices into a flat iterator"""
    return ( v for matrix in data for row in matrix for v in row )

def unflatten(data, n, m):
    """Convert a flat sequence (of ints) into a list of `n` by `m` matrices"""
    msize = n * m
    for chunk in chunks(data, msize):
        yield [ chunk[i:i+m] for i in range(0, msize, m) ]

如果sampledata是4x2矩阵的样本数组

rt = list(unflatten(flatten(sampledata), 4, 2)) 

是一个具有相同结构和值(但不是行数组而是元组)的列表。剩下的你能填吗?你知道吗

相关问题 更多 >