如果您的数据集很小,pickle/dill 方法很好。但是如果你正在处理大型数据集,我不会推荐它,因为它太慢了。
我只是将示例(迭代地)保存为 JSON 字符串。这背后的原因是因为保存整个 Dataset 对象需要花费大量时间,而且您需要像莳萝这样的序列化技巧,这使得序列化变得更慢。
此外,这些序列化程序会占用大量内存(其中一些甚至会创建数据集的副本),如果它们开始使用交换内存,那么您就完成了。该过程将花费很长时间,以至于您可能会在它完成之前终止它。
因此,我最终采用以下方法:
- 遍历示例
- 将每个示例(即时)转换为 JSON 字符串
- 将该 JSON 字符串写入文本文件(每行一个示例)
- 加载时,将示例与字段一起添加到 Dataset 对象
def save_examples(dataset, savepath):
with open(savepath, 'w') as f:
# Save num. elements (not really need it)
f.write(json.dumps(total)) # Write examples length
f.write("\n")
# Save elements
for pair in dataset.examples:
data = [pair.src, pair.trg]
f.write(json.dumps(data)) # Write samples
f.write("\n")
def load_examples(filename):
examples = []
with open(filename, 'r') as f:
# Read num. elements (not really need it)
total = json.loads(f.readline())
# Save elements
for i in range(total):
line = f.readline()
example = json.loads(line)
# example = data.Example().fromlist(example, fields) # Create Example obj. (you can do it here or later)
examples.append(example)
end = time.time()
print(end - start)
return examples
然后,您可以通过以下方式简单地重建数据集:
# Define fields
SRC = data.Field(...)
TRG = data.Field(...)
fields = [('src', SRC), ('trg', TRG)]
# Load examples from JSON and convert them to "Example objects"
examples = load_examples(filename)
examples = [data.Example().fromlist(d, fields) for d in examples]
# Build dataset
mydataset = Dataset(examples, fields)
我使用 JSON 而不是 pickle、dill、msgpack 等的原因不是随意的。
我做了一些测试,结果如下:
Dataset size: 2x (1,960,641)
Saving times:
- Pickle/Dill*: >30-45 min (...or froze my computer)
- MessagePack (iterative): 123.44 sec
100%|██████████| 1960641/1960641 [02:03<00:00, 15906.52it/s]
- JSON (iterative): 16.33 sec
100%|██████████| 1960641/1960641 [00:15<00:00, 125955.90it/s]
- JSON (bulk): 46.54 sec (memory problems)
Loading times:
- Pickle/Dill*: -
- MessagePack (iterative): 143.79 sec
100%|██████████| 1960641/1960641 [02:23<00:00, 13635.20it/s]
- JSON (iterative): 33.83 sec
100%|██████████| 1960641/1960641 [00:33<00:00, 57956.28it/s]
- JSON (bulk): 27.43 sec
*与其他答案类似的方法