我正在尝试将numpy的MaskedArray子类化以添加属性,但是似乎无法获得正确的结果。

我首先按照the example继承了numpy.ndarray的子类,但效果很好。

然后我尝试将numpy.ma.MaskedArray子类化,如下所示:

import numpy as np

class MyMaskedArray(np.ma.MaskedArray):

    def __new__(cls, input_array, info=None):
        obj = np.asarray(input_array).view(cls)
        obj.info = info
        return obj

    def __array_finalize__(self, obj):
        if obj is None: return
        self.info = getattr(obj, 'info', None)
        super(MyMaskedArray, self).__array_finalize__(obj)

arr = np.arange(5)
obj = MyMaskedArray(arr, info='information')
print obj.info
print obj[1:].info

导致
information
None

我曾两次期望“信息”。

obj = np.asarray(input_array).view(cls)obj = np.ma.MaskedArray(input_array).view(cls)替换obj = np.ma.MaskedArray.__new__(cls, input_array)行并不能解决该问题(我采用这种方式,因为我想在子类的 future 版本中将*args**kwargs传递给__new__。)

注意,与MaskedArray.__array_finalize子类的示例相反,我还必须在子类的__array_finalize__中添加对ndarray的调用。如果我不这样做,则找不到_mask属性。

也许有人可以启发我:
  • 如何获取obj[1:].info以保留原始obj.info
  • 为什么ndarray不需要对__array_finalize__的父类(super class)调用,但是MaskedArray却需要(但更多的问题)。

  • 我想对MaskedArray进行子类化,而不是编写一个容器类,因为后者将失去MaskedArray附带的一些便利。

    (注意:这与this question不同,因为我已经“解决”了__init__/__new__问题。)

    最佳答案

    为了使您的切片按您希望的方式工作,您可能需要重载__getitem__:

    def __getitem__(self, item):
        out = np.ma.MaskedArray.__getitem__(self, item)
        out.info = self.info
        return out
    

    同上__setitem__

    如果您的info属性相对简单(例如在您的示例中),则可能需要查看_optinfoMaskedArray属性,该属性是专为此目的而设计的:它只是一个字典,用于存储必须以某种方式保留的某些信息。这是一个例子:
    class MyMaskedArray(np.ma.MaskedArray):
    
        def __new__(cls, input_array, info=None):
            obj = np.asarray(input_array).view(cls)
            obj._optinfo['info'] = info
            return obj
    
        @property
        def info(self):
            return self._optinfo.get('info', None)
    

    请注意,此处.info是只读属性,但使其可写很简单。

    关于 __array_finalize__
    我不确定我是否理解您的问题:ndarray本身就是父类(super class)。 MaskedArrayndarray的子类,因此需要定义__array_finalize__方法,该方法特别说明如何设置掩码(通过_mask参数)。检查此link以获取有关子类化的更多信息。

    在您的示例中,您使用自己的__array_finalize__设置.info属性。在这种情况下,您必须调用父方法MaskedArray.__array_finalize__,它是基本的Python子类化。请注意,如果您采用__array_finalize__的方式,则不必显式定义_optinfo

    注意
  • 实际上,__array_prepare____array_wrap__方法用于准备ndarray子类的实例,然后对其应用函数并处理函数
  • 的结果。

    关于python - 子类化numpy.ma.MaskedArray,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14564656/

    10-11 15:22