Pickle 替代方案

34

我试图序列化一个大型列表(约10**6行,每行包含约20个值),以便稍后由自己使用(因此pickle的安全性不成问题)。

列表的每一行都是一组值的元组,这些值来自某个SQL数据库。到目前为止,我看到过datetime.datetime、字符串、整数和NoneType,但我可能最终还需要支持其他数据类型。

对于序列化,我考虑了pickle(cPickle)、json和纯文本——但只有pickle保存了类型信息:json无法序列化datetime.datetime,而纯文本具有其明显的缺点。

但是,对于这么大的数据,cPickle的速度相当慢,我正在寻找更快的替代方法。


1
你考虑过将它转储到SQLite数据库中吗? - rmmh
实际上 - 我没有。可能是最简单的... - Guy Adini
8个回答

16

Pickle是相当快的,只要你不使用(默认的)ASCII协议。只需确保使用protocol=pickle.HIGHEST_PROTOCOL进行转储。


4
需要翻译的内容:需要注意的是,根据文档,在Python3中默认的格式实际上是二进制格式。http://docs.python.org/3.4/library/pickle.html?highlight=pickle#pickle - Seanny123
3
更好的语义替代方案是 protocol=pickle.HIGHEST_PROTOCOL - Martin Thoma
1
谢谢,@moose!从 protocol=-1 更新。 - Jake Biesinger
使用以下代码将数据存储到文件中:pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL) - MrMartin
2
最高协议不断变化,任何负数都使用最高协议。如果您在Python 3.8中将某些内容持久化到最高协议(即4,而在3.7中为3),并升级到使用协议5作为最高协议的较新版本Python,则反序列化时会出现问题。 - nurettin

8

根据您要存储的确切内容,还有其他替代方案:

比较它们的方式是:

  • 易用性/编程语言支持/工具支持
  • 可读性
  • 存储大小
  • 读取时间
  • 写入时间
  • 功能:(1)追加数据(2)读取单行(3)具有模式

7
协议缓冲区是一种灵活,高效,自动化的机制,用于序列化结构化数据 - 可以将其视为XML,但更小,更快且更简单。
与XML相比具有以下优势:
- 更简单 - 大小是XML的3到10倍 - 速度是XML的20到100倍 - 不太模棱两可 - 生成的数据访问类在编程中更易于使用
参考链接:https://developers.google.com/protocol-buffers/docs/pythontutorial

5

我认为你应该看一下PyTables。它应该非常快,至少比使用关系型数据库更快,因为它非常灵活,不会强制实施任何读写限制,而且你可以获得更好的数据管理接口,至少与pickle相比是这样。


3

3
对于数十万个简单(最多与JSON兼容)复杂度的Python对象,我发现通过结合以下技术可以达到最佳的简洁、速度和大小组合: 相比于picklecPickle选项,它的性能提高了数倍。
with gzip.open(filename, 'wb') as f:
    ubjson.dump(items, f)


with gzip.open(filename, 'rb') as f:
    return ubjson.load(f)

未定义的项 - Cybernetic
我猜 item=pandas 数据框。 - user88484
items 是 Python 中任何兼容 JSON 的对象。 - Apalala

2
我通常将数据序列化为纯文本(*.csv)格式,因为我发现它是最快的。csv模块工作得很好。请参见http://docs.python.org/library/csv.html 如果你需要处理字符串的unicode编码,请查看末尾的UnicodeReader和UnicodeWriter示例。
如果你为自己未来的使用序列化数据,我想知道每个csv列都有相同的数据类型(例如,字符串总是在第2列)就足够了。

这对我来说不太好 - 因为它不维护类型信息,所以我必须循环遍历数据并进行转换,这非常慢(至少在我的实现中,使用列表推导式的列表推导式)。 - Guy Adini

1

Avro 似乎是一个有前途且设计良好但尚未流行的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接