python3 中的 _pickle 不适用于大数据保存
Posted
技术标签:
【中文标题】python3 中的 _pickle 不适用于大数据保存【英文标题】:_pickle in python3 doesn't work for large data saving 【发布时间】:2015-06-24 14:18:37 【问题描述】:我正在尝试应用_pickle
将数据保存到磁盘上。但是调用_pickle.dump
的时候报错了
OverflowError: cannot serialize a bytes object larger than 4 GiB
这是使用_pickle
的硬性限制吗? (cPickle
用于 python2)
【问题讨论】:
【参考方案1】:是的,这是一个硬编码限制;来自save_bytes
function:
else if (size <= 0xffffffffL)
// ...
else
PyErr_SetString(PyExc_OverflowError,
"cannot serialize a bytes object larger than 4 GiB");
return -1; /* string too large */
协议使用 4 个字节将对象的大小写入磁盘,这意味着您最多只能跟踪 232 == 4GB 的大小。
如果您可以将bytes
对象分解为多个对象,每个对象小于 4GB,当然您仍然可以将数据保存到 pickle 中。
【讨论】:
谢谢!是否可以将大文件保存在磁盘上并绕过此限制? @Jake0x32:不带泡菜;这是协议中的硬限制。将您的bytes
对象分解成更小的部分。
@MartijnPieters 我在尝试腌制分类器from sklearn.svm import SVC
时遇到了同样的问题。我如何将对象分解成字节然后腌制?【参考方案2】:
在具有 PEP 3154 和 Pickle 4.0 的 Python 3.4 中不再存在https://www.python.org/dev/peps/pep-3154/
但你需要说你要使用第 4 版协议:https://docs.python.org/3/library/pickle.html
pickle.dump(d, open("file", 'w'), protocol=4)
【讨论】:
这样打开文件是不是好办法?我的意思是不关闭它。 @1a1a11a 最好使用“with”语句打开文件以确保文件关闭。但是,一旦调用 pickle.dump 返回,对文件对象的引用计数就会下降到零,因此它会立即进行垃圾收集,并且无论如何都会关闭文件。 @jlund3 谢谢。我已经想知道如果 Python 有垃圾收集器,“with”到底是什么用途。我猜这都是关于范围界定的。【参考方案3】:对于为什么泡菜不起作用,上面有一个很好的答案。 但它仍然不适用于 Python 2.7,这是一个问题 如果你还在 Python 2.7 并且想要支持大 文件,尤其是 NumPy(超过 4G 的 NumPy 数组失败)。
您可以使用 OC 序列化,该序列化已更新为适用于数据 4G。有一个 Python C 扩展模块可从:
http://www.picklingtools.com/Downloads
查看文档:
http://www.picklingtools.com/html/faq.html#python-c-extension-modules-new-as-of-picklingtools-1-6-0-and-1-3-3
但是,这里有一个简短的总结:有 ocdumps 和 ocloads,非常像 pickle 的转储和加载::
from pyocser import ocdumps, ocloads
ser = ocdumps(pyobject) : Serialize pyobject into string ser
pyobject = ocloads(ser) : Deserialize from string ser into pyobject
OC 序列化速度提高了 1.5-2 倍,并且还可以与 C++ 一起使用(如果您正在混合语言)。它适用于所有内置类型,但不适用于类 (部分是因为它是跨语言的,而且很难构建 C++ 类 来自 Python)。
【讨论】:
以上是关于python3 中的 _pickle 不适用于大数据保存的主要内容,如果未能解决你的问题,请参考以下文章