我无法让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: {} {}
任何关于我做错的提示都会非常感激!
答案 0 :(得分:1)
看看:https://mail.python.org/pipermail/python-list/2011-April/601275.html
你遇到的问题是腌制C扩展类型(ndarray子类型)的结果。我不是numpy数组内部工作的专家,但我猜测那里的代码可以手动处理酸洗numpy数据。由于您的SubArray
类是ndarray的子类,因此您需要覆盖numpy使用的酸洗方法。
所以,AFAIK你的选择是:
object
的所有类子类,并让它们包含您需要能够挑选/取消选择的相应数据。如果你要坚持使用pickle进行转储和加载数据,那么选项#3就是我的选择。 pickle模块的设计考虑了纯python对象,而不是扩展类型。