3 回答
TA贡献1900条经验 获得超5个赞
PyTable默认使用最高协议,这里硬编码:https ://github.com/PyTables/PyTables/blob/50dc721ab50b56e494a5657e9c8da71776e9f358/tables/atom.py#L1216
作为一种解决方法,您可以pickle在编写 HDF 文件的客户端 A 上对模块进行猴子补丁。您应该在导入之前执行此操作pandas:
import pickle
pickle.HIGHEST_PROTOCOL = 4
import pandas
df.to_hdf(file, key)
现在 HDF 文件已使用 pickle 协议版本 4 而不是版本 5 创建。
TA贡献1829条经验 获得超7个赞
更新:我错误地认为这是不可能的。事实上,基于@PiotrJurkiewicz 的优秀“monkey-patch”建议,这里有一个简单的上下文管理器,可以让我们临时更改最高的 pickle 协议。它:
隐藏猴子补丁,并且
在上下文之外没有副作用;它可以随时使用,无论之前是否进口泡菜,无论是在熊猫之前还是之后。
这是代码(例如在文件中pickle_prot.py
):
import importlib
import pickle
class PickleProtocol:
def __init__(self, level):
self.previous = pickle.HIGHEST_PROTOCOL
self.level = level
def __enter__(self):
importlib.reload(pickle)
pickle.HIGHEST_PROTOCOL = self.level
def __exit__(self, *exc):
importlib.reload(pickle)
pickle.HIGHEST_PROTOCOL = self.previous
def pickle_protocol(level):
return PickleProtocol(level)
writer中的用法示例:
import pandas as pd
from pickle_prot import pickle_protocol
pd.DataFrame(['hello', 'world']).to_hdf('foo_0.h5', 'x')
with pickle_protocol(4):
pd.DataFrame(['hello', 'world']).to_hdf('foo_1.h5', 'x')
pd.DataFrame(['hello', 'world']).to_hdf('foo_2.h5', 'x')
并且,使用一个简单的测试阅读器:
import pandas as pd
from glob import glob
for filename in sorted(glob('foo_*.h5')):
try:
df = pd.read_hdf(filename, 'x')
print(f'could read {filename}')
except Exception as e:
print(f'failed on {filename}: {e}')
现在,在用 py38 编写后尝试在 py37 中读取,我们得到:
failed on foo_0.h5: unsupported pickle protocol: 5
could read foo_1.h5
failed on foo_2.h5: unsupported pickle protocol: 5
但是,使用相同的版本(37 或 38)进行读写,我们当然也不例外。
TA贡献1816条经验 获得超4个赞
我(曾经)面临同样的问题......我“知道”如何解决它,我认为你也这样做......解决方案是将整个数据重新处理为泡菜(或 csv)并重新转换它在 python3.7 到 hdf5(只知道协议 4)。
流程是这样的:python3.8 -> hdf5 -> python3.8 -> csv/pickle -> python3.7 -> hdf5(与两个版本兼容)
我避开了这条路线,因为我导出了数据框的大量数据,从而创建了大量文件。
您实际上仅限于使用 python3.7 吗?我受到 tensorflow 的限制,它目前仅支持 3.7(官方),但您可以安装 tensorflow-nightly-build,它适用于 python 3.8
检查您是否可以迁移到 3.8,这肯定会解决您的问题。:)
添加回答
举报