我有一个(非常大的)数据集。大约为200,000个二进制向量的大小为800.
数据集位于“压缩表示”中的(.txt ascii编码)文件中。意思是,该文件中的每一行代表一个矢量的外观,而不是800个字符的零和一个
例如,假设该文件中的第i行如下所示:
12 14 16 33 93 123 456 133
这意味着第i个向量是一个向量,其第12'第14',第16,......第133'索引保持值1,其余为零。
文件的大小略大于30MB。
现在,由于我使用这些数据来提供神经网络,这个数据需要一些预处理,以便将其转换为网络所需的内容:大小为250,000的列表,其中该列表中的每个元素都是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]]]
(仅代替4x2我有20x40矩阵)。
所以我写了两个函数:load_data()
- 解析文件并返回800个二进制列表的列表,reshape()
- 将列表重新整形为20x40矩阵。
毋庸置疑,当load_data()
和reshape()
正在运行时,我糟糕的笔记本电脑非常难用。完成预处理大约需要7到9分钟,而在那段时间我可以在我的笔记本电脑上做任何其他事情。即使最小化IDE窗口也是一项非常困难的任务
由于我使用这些数据来调整神经网络,我发现自己经常杀死正在运行的进程,重新调整网络,然后重新开始 - 每次重启都会导致调用load_data()
后跟{{1} }。
所以,我决定快速完成这个加载数据的痛苦过程 - >转换为二元向量 - >重塑它。
我想从文件中加载数据,转换为二进制向量,重新整形并将其序列化为文件reshape()
。
现在,每当我需要提供网络时,我都可以从my_input
反序列化数据,并为我节省大量时间。
我就这样做了:
my_input
问题在于:
结果文件很大;尺寸为1.7GB,看起来游戏不值得用蜡烛(我希望我使用它正确),因为加载它需要太多时间(没有测量多少,我只是试图加载它,并且9-10分钟后,我放弃并杀死了这个过程)。
为什么生成的文件比原始文件大得多(我希望它更大,但不是那么多)?
有没有另一种方法来编码数据(顺序化/反序列化),这将导致一个较小的文件,并值得我的时间?
或者,或者,如果任何人都可以提出一个更好的方法来加快速度(除了购买更快的计算机),这也会很棒。
p.s在进行反序列化时,我不关心兼容性问题。这个数据将被反序列化的唯一地方是在我的计算机上。
答案 0 :(得分:2)
如果您要为数据中的每个值存储一点,那么最终会得到一个25MB的文件;所以你的“压缩”方案实际上使你的文件更大。您当前方案的唯一优势是您可以将数据存储在ascii中。
计算:
250.000 * 800 bits = 250.000 * 100 bytes = 25.000.000 bytes = 25 MB
因此,只需手动存储位模式,将其重新读入并继续计算。
修改:看起来阻力最小的路径是使用第三方模块packbits
(即您需要下载它)。您必须首先将您的长矩阵列表平移到一个平面列表中(作为迭代器),将其写为一系列位(注意:每个32位int可以“打包”32个值 - 而不仅仅是您在评论中建议的一个值),然后对输入进行反向转换。 List-flattening食谱只有十几个(参见here选项),但这里有一个补充的unflattening代码。
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
是4 x 2矩阵的样本数组,
rt = list(unflatten(flatten(sampledata), 4, 2))
是一个具有相同结构和值的列表(但是元组而不是行数组)。你可以填写其余的吗?