6

我有一个代码框架,其中涉及使用 dill 转储会话。这曾经工作得很好,直到我开始使用熊猫。以下代码在 CentOS 6.5 版上引发 PicklingError:

import pandas
import dill
dill.dump_session('x.dat')

问题似乎源于 pandas.algos。事实上,运行它来重现错误就足够了:

import pandas.algos
import dill
dill.dump_session('x.dat') / dill.dumps(pandas.algos)

错误是pickle.PicklingError: Can't pickle <cyfunction lambda1 at 0x1df3050>: it's not found as pandas.algos.lambda1

问题是,我的电脑上没有出现这个错误。它们都有相同版本的 pandas (0.14.1)、dill (0.2.1) 和 python (2.7.6)。

看着坏对象,我得到:

>>> dill.detect.badobjects(pandas.algos, depth = 1)
{'__builtins__': <module '__builtin__' (built-in)>, 
'_return_true': <cyfunction lambda2 at 0x1484d70>, 
'np': <module 'numpy' from '/usr/local/lib/python2.7/site-packages/numpy-1.8.2-py2.7-linux-x86_64.egg/numpy/__init__.pyc'>, 
'_return_false': <cyfunction lambda1 at 0x1484cc8>, 
'lib': <module 'pandas.lib' from '/home/talkr/.local/lib/python2.7/site-packages/pandas/lib.so'>}

这似乎是由于pandas.algos两个操作系统的不同处理(可能是不同的编译器?)。在我的电脑上,dump_session没有错误的地方pandas.algos._return_false<cyfunction <lambda> at 0x06DD02A0>,而在 CentOS 上是<cyfunction lambda1 at 0x1df3050>. 为什么处理方式不同?

4

1 回答 1

5

我没有看到您在 Mac 上看到的内容。这是我看到的,使用相同版本的pandas. 我确实看到您使用的是不同版本的dill. 我正在使用来自 github 的版本。我将检查是否对保存模块或全局变量进行了调整,dill这可能会对某些发行版产生影响。

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> import dill
>>> dill.detect.trace(True)
>>> dill.dump_session('x.pkl')
M1: <module '__main__' (built-in)>
F2: <function _import_module at 0x1069ff140>
D2: <dict object at 0x106a0b280>
M2: <module 'dill' from '/Users/mmckerns/lib/python2.7/site-packages/dill-0.2.2.dev-py2.7.egg/dill/__init__.pyc'>
M2: <module 'pandas' from '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pandas/__init__.pyc'>

这是我得到的pandas.algos

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas.algos
>>> import dill
>>> dill.dumps(pandas.algos)
'\x80\x02cdill.dill\n_import_module\nq\x00U\x0cpandas.algosq\x01\x85q\x02Rq\x03.'

这是我得到的pandas.algos._return_false

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> import pandas.algos
>>> dill.dumps(pandas.algos._return_false)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mmckerns/lib/python2.7/site-packages/dill-0.2.2.dev-py2.7.egg/dill/dill.py", line 180, in dumps
    dump(obj, file, protocol, byref, file_mode, safeio)
  File "/Users/mmckerns/lib/python2.7/site-packages/dill-0.2.2.dev-py2.7.egg/dill/dill.py", line 173, in dump
    pik.dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 317, in save
    self.save_global(obj, rv)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <cyfunction lambda1 at 0x10d403cc8>: it's not found as pandas.algos.lambda1

所以,我现在可以重现您的错误。

根据它的构建方式,这看起来像是一个不可拾取的对象。但是,它应该可以在模块内腌制……就像我一样。 您似乎已经确定了您在 Pandas 在 CentOS 上构建的对象中看到的差异。

查看pandas代码库,pandas.algos是一个pyx文件……所以就是cython. 这是代码。

_return_false = lambda self, other: False

如果在一个.py文件中,我知道它会序列化。我不知道生成的 lambdas 是如何dill工作的cython……(例如 lambda cyfunction)。

看起来有一个提交(https://github.com/pydata/pandas/commit/73c71dfca10012e25c829930508b5d6f7ccad5ff_return_false被移到类之外进入模块范围。你在 CentOS 和你的 PC 上都看到了吗?可能是针对不同发行版的 v0.14.1 被切断了略有不同的 git 版本……取决于您安装 pandas 的方式。

显然,我可以lambda1通过尝试获取对象的源来获取 a……对于 lambda,如果它无法获取源,dill将按名称获取……显然它被命名了lambda1……即使它没有出现在.pyx 文件。也许这是由于如何cython构建 lambdas。

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas.algos
>>> import dill
>>> dill.source.importable(pandas.algos._return_false)
'from pandas import lambda1\n'

差异可能来自cython...,因为代码是从.pyxin生成的pandas。你的版本是cython什么?我的是 0.20.2。

于 2014-09-01T21:09:33.300 回答