【发布时间】:2019-07-28 04:19:23
【问题描述】:
关于将元数据附加到 Pandas 对象并让该数据在 pickle/unpickle 过程中存活的问题是一个长期存在的问题。我看到一些非常古老的答案,基本上说你不能。希望这个问题的最新答案是肯定的。我正在使用 Pandas 0.23.3。
我制作了一些 Pandas DataFrame 子类。我想我知道如何正确地做到这一点。我有一个_constructor 方法,我的__init__ 方法可以处理BlockManager 对象。当我创建元数据属性时,我抑制了 UserWarning,它警告我没有在 DataFrame 本身中创建列,在我的情况下这很好。
当我想将 DataFrame 保存到磁盘时,我调用my_fancy_df.to_pickle(file_path)。当我想重新加载它时,我使用my_fancy_df = pandas.read_pickle(file_path)。 MY 元数据被删除。 Pandas 本身具有可以很好地腌制和解封的元数据,例如DataFrame.name 属性。我想为我的属性复制这种行为。
我可以在我的子类中拦截.to_pickle 调用,并安排将元数据分别写入同一个文件对象。但我没有看到改变数据重新加载方式的等效方法。 read_pickle 函数是通用的,位于 Pandas 命名空间中,不属于 DataFrame 类。
我可能会在我的班级外部编写一个自定义的 unpickling 函数并使用它......它看起来很笨拙。如果有一种优雅的方式来完成这项工作,我还没有找到。
我也没有死心塌地使用泡菜。如果HDF5更合适,比如我可以切换。不过,我确实需要在 DataFrame 中腌制任意 Python 数据类型。单元格中的内容不仅仅是字符串和数字,我也有元组,在我构建的一个子类中,我什至将 DataFrames 放在了 DataFrames 中。
感谢您的建议。
【问题讨论】:
-
有趣的是,另一位用户似乎比你早一个小时问了a very similar question。
-
跟进我自己:我的自定义元数据甚至无法在 SLICE 操作中幸存下来,所以也许我应该先了解一下。当 BlockManager 被传递时,看起来我可能需要做的不仅仅是
super().__init__(arg[0])在我的__init__中。保存和恢复到磁盘可能是一个相关的问题, -
是的,@MichaelKolber,这很有趣。拥有这种能力显然很有趣。
-
查看subclassing pandas data structures 上的文档,尤其是defining original properties 上的部分。
-
谢谢@root,自从我上次查看 Pandas 子类化文档以来,似乎有些事情实际上发生了变化。
标签: python pandas dataframe pickle