【问题标题】:Pandas compiled from source: default pickle behavior changed从源代码编译的 Pandas:默认泡菜行为已更改
【发布时间】:2013-12-07 17:55:05
【问题描述】:

我刚刚从源代码编译并安装了 pandas(克隆的 github 存储库,>>> setup.py install)。

碰巧模块pickle 的对象序列化/反序列化的默认行为发生了变化,可能部分被pandas 内部模块覆盖。

我有很多通过“标准”pickle 序列化的数据类,显然我不能再反序列化了;特别是,当我尝试反序列化一个类文件(肯定工作)时,我得到了这个错误

In [1]: import pickle

In [2]: pickle.load(open('pickle_L1cor_s1.pic','rb'))
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-88719f8f9506> in <module>()
----> 1 pickle.load(open('pickle_L1cor_s1.pic','rb'))

/home/acorbe/Canopy/appdata/canopy-1.1.0.1371.rh5-x86_64/lib/python2.7/pickle.pyc in load(file)
   1376
   1377 def load(file):
-> 1378     return Unpickler(file).load()
   1379
   1380 def loads(str):

/home/acorbe/Canopy/appdata/canopy-1.1.0.1371.rh5-x86_64/lib/python2.7/pickle.pyc in load(self)
    856             while 1:
    857                 key = read(1)
--> 858                 dispatch[key](self)
    859         except _Stop, stopinst:
    860             return stopinst.value

/home/acorbe/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas-0.12.0_1090_g46008ec-py2.7-linux-x86_64.egg/pandas/compat/pickle_compat.pyc in load_reduce(self)
     28
     29         # try to reencode the arguments
---> 30         if self.encoding is not None:
     31             args = tuple([ arg.encode(self.encoding) if isinstance(arg, string_types)     else arg for arg in args ])
     32             try:

AttributeError: Unpickler instance has no attribute 'encoding'

我有相当大的代码依赖于此,但它崩溃了。有什么快速的解决方法吗?我怎样才能再次获得默认的泡菜行为?

任何帮助表示赞赏


编辑:

我意识到我愿意解开的是一个字典列表,其中每个包含几个 DataFrames。这就是熊猫发挥作用的地方。

我通过@Jeff github.com/pydata/pandas/pull/5661 应用了补丁。 出现另一个错误(可能与this 有关)。

In [4]: pickle.load(open('pickle_L1cor_s1.pic','rb'))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-88719f8f9506> in <module>()
----> 1 pickle.load(open('pickle_L1cor_s1.pic','rb'))

/home/acorbe/Canopy/appdata/canopy-1.1.0.1371.rh5-x86_64/lib/python2.7/pickle.pyc in load(file)
   1376
   1377 def load(file):
-> 1378     return Unpickler(file).load()
   1379
   1380 def loads(str):

/home/acorbe/Canopy/appdata/canopy-1.1.0.1371.rh5-x86_64/lib/python2.7/pickle.pyc in load(self)
    856             while 1:
    857                 key = read(1)
--> 858                 dispatch[key](self)
    859         except _Stop, stopinst:
    860             return stopinst.value

/home/acorbe/Canopy/appdata/canopy-1.1.0.1371.rh5-x86_64/lib/python2.7/pickle.pyc in             load_reduce(self)
   1131         args = stack.pop()
   1132         func = stack[-1]
-> 1133         value = func(*args)
   1134         stack[-1] = value
   1135     dispatch[REDUCE] = load_reduce

TypeError: _reconstruct: First argument must be a sub-type of ndarray

Pandas 版本的编码数据是(来自 Canopy 包管理器)

Size: 7.32 MB
Version: 0.12.0
Build: 2
Dependencies:
 numpy 1.7.1
 python_dateutil
 pytz 2011n

  md5: 7dd4385bed058e6ac15b0841b312ae35

我不确定我能否提供我试图解压的文件的最小示例。 它们非常大(O(100MB))并且它们具有一些非平凡的依赖关系。

【问题讨论】:

  • 你能显示你所做的确切代码以及泡菜文件吗(如果你可以的话,来自 Dropbox 的链接)
  • 你可以在加载 pandas 之前解压(作为一种解决方法)
  • @Jeff,我发布的正是我使用的代码。没有明确涉及熊猫。在我完成 pandas 安装后,加载我正在使用的文件的 unpickle 调用(甚至与 pandas 无关)崩溃了。文件大于 100mb
  • 我需要一些东西来重现。您必须在此之前加载熊猫,否则代码将不存在。你能发布一个文件的链接吗?
  • 试试这个分支(或者你可以暂时编辑代码,只有几行),lmk:github.com/pydata/pandas/pull/5661

标签: python pandas pickle


【解决方案1】:

大师刚刚被这个issue更新了。

这个文件被简单地读取:

 result = pd.read_pickle('pickle_L1cor_s1.pic')

腌制的对象是 pandas ndarray 的子类,而是现在的 NDFrameDataFramePanel 的相同基类。这样做有很多原因,主要是为了提高代码的一致性。有关更完整的说明,请参阅here

您看到的错误消息`TypeError: _reconstruct: First argument must be a sub-type of ndarray 是 python 默认 unpickler 确保被腌制的类层次结构与它正在重新创建的层次结构完全相同。由于 Series 在版本之间发生了变化,因此使用默认的 unpickler 不再可能,(恕我直言,这是 pickle 工作方式中的一个错误)。在任何情况下,pandas 都会取消 0.13 之前的具有 Series 对象的泡菜。

【讨论】:

  • 那么这是否意味着如果我有一个 numpy 函数在调用一个时返回一个系列或数据帧,这是一个需要解决的问题?
  • 我不这么认为;在 0.13 中尝试 unpickle 时,仅在 0.12 或之前保存的系列/帧。一个函数def就可以了
  • 啊,对不起,我的措辞可能很糟糕。有很多 numpy 函数在传递 Series 时仍然返回 Series。我认为这是一个功能,我可能曾多次依赖它,但你链接到的最新消息说也许我弄错了?
  • numpy 函数使用 array(几乎是所有这些,除了 np.where)在传递一个系列时返回一个系列。这是一个运行时功能,不会对泡菜产生影响。
  • 是的,让我困惑的是现场直播的内容。我误读了重构部分,这意味着如果我们在 Series 或 DataFrame 上应用 numpy 函数,我们现在应该只期望得到 ndarrays。一切都很好。 :^)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 2014-08-29
  • 2020-10-19
相关资源
最近更新 更多