Python 如何腌制numpy MaskedArray子类

Python 如何腌制numpy MaskedArray子类,python,numpy,pickle,Python,Numpy,Pickle,我很难让一个NumPyMaskedArray子类往返于pickle并保留额外的子类属性。以下是一个例子: import numpy as np import cPickle as pickle from numpy import ma class SubArray(np.ndarray): """Defines a generic np.ndarray subclass, that stores some metadata in the dictionary `info`.

我很难让一个NumPy
MaskedArray
子类往返于pickle并保留额外的子类属性。以下是一个例子:

import numpy as np
import cPickle as pickle
from numpy import ma


class SubArray(np.ndarray):
    """Defines a generic np.ndarray subclass, that stores some metadata
    in the  dictionary `info`."""
    def __new__(cls, arr, info={}):
        x = np.asanyarray(arr).view(cls)
        x.info = info
        return x

    def __array_finalize__(self, obj):
        self.info = getattr(obj, 'info', {'ATTR': 'MISSING'})
        return


class MSubArray(SubArray, ma.MaskedArray):
    def __new__(cls, data, info={}, mask=ma.nomask, dtype=None):
        subarr = SubArray(data, info)
        _data = ma.MaskedArray.__new__(cls, data=subarr, mask=mask, dtype=dtype)
        _data.info = subarr.info
        return _data

    def __array_finalize__(self, obj):
        ma.MaskedArray.__array_finalize__(self, obj)
        SubArray.__array_finalize__(self, obj)
        return

ms = MSubArray([1, 2], info={'a': 1})
print('Pre-pickle:', ms.info, ms.data.info)

pkl = pickle.dumps(ms)
ms_from_pkl = pickle.loads(pkl)
print('Post-pickle:', ms_from_pkl.info, ms_from_pkl.data.info)
这将产生:

Pre-pickle: {'a': 1} {'a': 1}
Post-pickle: {} {}
任何关于我做错了什么的提示都将不胜感激

看看:

您遇到的问题是酸洗C扩展类型(ndarray子类型)的结果。我不是numpy数组内部工作原理方面的专家,但我猜有一些代码可以手动处理酸洗numpy数据。由于您的
子数组
类是ndarray的子类,因此您需要克服numpy使用的酸洗方法

那么,您的选择是:

  • 在pickle.dumps和pickle.load上放置垫片(在其达到C级之前)
  • 更新numpy pickle方法,以便它们检查子类
  • 将所有类设置为
    对象的子类
    ,并使它们包含能够pickle/unpickle的适当数据

  • 如果您坚持使用pickle来转储和加载数据,那么选项#3就是我的选择。pickle模块的设计考虑了纯python对象,而不是扩展类型。

    这个示例是一个非常简化的真实版本,它正确地pickle/unpickle了numpy子类。真正的问题出现在
    MSubArray.\uuuuu new\uuuuu
    的等价物中,它在取消pickle过程中传递了
    data
    类型为
    MSubArray
    的对象,该对象没有预期的
    MSubArray
    属性。这让它很不开心,但不再如此。谢谢你的帮助,让我朝着正确的方向前进。在这个问题中可以找到解决方案和一些见解