【问题标题】:Comparing ndarray derived classes比较 ndarray 派生类
【发布时间】:2015-12-04 04:57:17
【问题描述】:

按照here 的说明,我创建了一个 ndarray 的子类,它为 ndarray 类添加了新属性。现在我想为新类定义一个比较运算符,它除了比较数据之外,还比较属性的值。所以我尝试了这个:

def __eq__(self, other):
    return (self._prop1 == other._prop1) and \
           (self._prop2 == other._prop2) and \
           (self.data == other.data)

这允许像T1 == T2 这样的比较并返回一个布尔值。但是,由于我想将这些数组与其他 ndarray 互换使用,我希望比较返回一个布尔数组。如果我没有定义我的__eq__ 函数,那么比较会返回一个布尔数组,但是我无法检查属性。如何将两者结合起来?

【问题讨论】:

  • 看起来 ndarray 如果属性(例如形状)不匹配,则返回标量 True/False,并且仅当它们都匹配时才返回布尔数组。使用一个或ifs,如果它们失败,您应该能够返回您的属性测试,并且else 返回data 测试。允许自己多个returns。这样写代码更容易。
  • @hpaulj 将我的自定义属性和基础数据的比较分开是一个不错的建议。但是,问题仍然是数据属性的比较本身返回的是布尔值,而不是数组。如何从比较运算符中调用 numpy 的逐元素比较?
  • 看看掩码数组是如何处理这个问题的:np.ma.core.MaskedArray.__eq__

标签: python numpy


【解决方案1】:

根据suggestion by hpaulj,我通过查看np.ma.core.MaskedArray.__eq__ 了解了如何做到这一点。这是供参考的最低实现。主要思想是在self 的基类类型DerivedArray 的视图上调用numpy __eq__()

class DerivedArray(np.ndarray):
    def __new__(cls, input_array, prop1, prop2):       
        _baseclass = getattr(input_array, '_baseclass', type(input_array))
        obj = np.asarray(input_array).view(cls)

        obj._prop1    = prop1
        obj._prop2    = prop2
        obj._baseclass = _baseclass
        return obj

    def __array_finalize__(self, obj):
        if obj is None:
            return
        else:
            if not isinstance(obj, np.ndarray):
                _baseclass = type(obj)
            else:
                _baseclass = np.ndarray

        self._prop1    = getattr(obj, '_prop1', None)
        self._prop2    = getattr(obj, '_prop2', None)
        self._baseclass= getattr(obj, '_baseclass', _baseclass)

    def _get_data(self):
        """Return the current data, as a view of the original
        underlying data.
        """
        return np.ndarray.view(self, self._baseclass)

    _data = property(fget=_get_data)
    data  = property(fget=_get_data)

    def __eq__(self, other):
        attsame = (self._prop1 == other._prop1) and (self._prop2 == other._prop2)
        if not attsame: return False
        return self._data.__eq__(other)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 2020-10-04
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    相关资源
    最近更新 更多