Python: Serializing/de-serializing 海量数据
Python: Serializing/de-serializing huge amount of data
我有一个(非常大的)数据集。大约有 250,000 个二进制向量,每个大小为 800。
数据集位于 'compressed representation' 中的(.txt ascii 编码)文件中。意思是,该文件中的每一行都代表一个矢量的外观,而不是 800 个零和一的字符。
例如,假设该文件中的第 i 行如下所示:
12 14 16 33 93 123 456 133
这意味着第i个向量是第12个、第14个、第16个、...第133个索引值为1的向量,其余为零。
文件大小略大于 30MB。
现在,由于我使用这些数据来为神经网络提供数据,因此需要对这些数据进行一些预处理,以便将其转换为网络所期望的:大小为 250,000 的列表,其中该列表中的每个元素都是一个 20x40 矩阵(列表列表)0 和 1。
例如,如果我们将问题重新缩放为 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()
- 解析文件和 returns 800 个二进制列表的列表,以及 reshape()
- 将列表重塑为 20x40 矩阵。
不用说,当 load_data()
和 reshape()
为 运行 时,我可怜的笔记本电脑工作起来真的很辛苦。完成预处理大约需要 7-9 分钟,而在这段时间里,我可以用大麦在我的笔记本电脑上做任何其他事情。即使最小化 IDE window 也是一项极其困难的任务。
由于我使用这些数据来调整神经网络,我发现自己经常终止 运行 进程,重新调整网络,然后重新开始——每次重新启动都会调用 load_data()
,然后调用 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 分钟后,我放弃并终止了进程)。
为什么生成的文件比原始文件大这么多(我希望它更大,但没有那么大)?
是否有另一种编码数据的方法(serialize/de-serialize 明智),这将导致文件更小,并且值得我花时间?
或者,如果有人可以建议一种更好的方法来加快速度(除了购买更快的计算机之外),那也很棒。
p.s 我不关心反序列化的兼容性问题。此数据将被反序列化的唯一位置是在我的计算机上。
如果您要为数据中的每个值存储一点,您最终会得到一个 25MB 的文件;所以你的 "compression" 方案实际上让你的文件变大了。当前方案的唯一优点是您可以将数据存储在 ascii 中。
计算:
250.000 * 800 bits = 250.000 * 100 bytes = 25.000.000 bytes = 25 MB
所以只需手动存储位模式,读回它们并继续计算。
编辑: 看起来阻力最小的路径是使用第三方模块 packbits
(i.e. you need to download it). You must first flatten your long list of matrices into a flat list on the fly (as an iterator), write it out as a sequence of bits (note: every 32-bit int can be "packed" with 32 values-- not just one value as you suggest in the comments), then do the reverse conversion on input. List-flattening recipes are a dime a dozen (see 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
是您的 4 x 2 矩阵样本数组,
rt = list(unflatten(flatten(sampledata), 4, 2))
是具有相同结构和值的列表(但元组而不是行数组)。剩下的可以填吗?
我有一个(非常大的)数据集。大约有 250,000 个二进制向量,每个大小为 800。
数据集位于 'compressed representation' 中的(.txt ascii 编码)文件中。意思是,该文件中的每一行都代表一个矢量的外观,而不是 800 个零和一的字符。
例如,假设该文件中的第 i 行如下所示:
12 14 16 33 93 123 456 133
这意味着第i个向量是第12个、第14个、第16个、...第133个索引值为1的向量,其余为零。
文件大小略大于 30MB。
现在,由于我使用这些数据来为神经网络提供数据,因此需要对这些数据进行一些预处理,以便将其转换为网络所期望的:大小为 250,000 的列表,其中该列表中的每个元素都是一个 20x40 矩阵(列表列表)0 和 1。
例如,如果我们将问题重新缩放为 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()
- 解析文件和 returns 800 个二进制列表的列表,以及 reshape()
- 将列表重塑为 20x40 矩阵。
不用说,当 load_data()
和 reshape()
为 运行 时,我可怜的笔记本电脑工作起来真的很辛苦。完成预处理大约需要 7-9 分钟,而在这段时间里,我可以用大麦在我的笔记本电脑上做任何其他事情。即使最小化 IDE window 也是一项极其困难的任务。
由于我使用这些数据来调整神经网络,我发现自己经常终止 运行 进程,重新调整网络,然后重新开始——每次重新启动都会调用 load_data()
,然后调用 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 分钟后,我放弃并终止了进程)。
为什么生成的文件比原始文件大这么多(我希望它更大,但没有那么大)?
是否有另一种编码数据的方法(serialize/de-serialize 明智),这将导致文件更小,并且值得我花时间?
或者,如果有人可以建议一种更好的方法来加快速度(除了购买更快的计算机之外),那也很棒。
p.s 我不关心反序列化的兼容性问题。此数据将被反序列化的唯一位置是在我的计算机上。
如果您要为数据中的每个值存储一点,您最终会得到一个 25MB 的文件;所以你的 "compression" 方案实际上让你的文件变大了。当前方案的唯一优点是您可以将数据存储在 ascii 中。
计算:
250.000 * 800 bits = 250.000 * 100 bytes = 25.000.000 bytes = 25 MB
所以只需手动存储位模式,读回它们并继续计算。
编辑: 看起来阻力最小的路径是使用第三方模块 packbits
(i.e. you need to download it). You must first flatten your long list of matrices into a flat list on the fly (as an iterator), write it out as a sequence of bits (note: every 32-bit int can be "packed" with 32 values-- not just one value as you suggest in the comments), then do the reverse conversion on input. List-flattening recipes are a dime a dozen (see 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
是您的 4 x 2 矩阵样本数组,
rt = list(unflatten(flatten(sampledata), 4, 2))
是具有相同结构和值的列表(但元组而不是行数组)。剩下的可以填吗?