2015-12-03 29 views
0

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

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

这使得像T1 == T2比较,并返回一个布尔值。但是,因为我想与其他ndarrays交替使用这些数组,我希望比较返回一个布尔数组。如果我没有定义我的__eq__函数,那么比较返回一个布尔数组,然后我无法检查属性。我怎么能结合这两个?

+0

看起来像'ndarray'返回标量如果属性(例如形状)不匹配则为真/假,只有匹配时才返回布尔数组。使用一个或'ifs',如果它们失败,你应该能够返回属性测试,'else'返回'data'测试。让自己多次'返回'。以这种方式编写代码更容易。 – hpaulj

+0

@hpaulj分隔我的自定义属性和底层数据的比较是一个很好的建议。但是,问题仍然是数据属性本身的比较返回一个布尔值,而不是数组。我如何从比较运算符调用numpy的按元素进行比较? – deepak

+1

看看masked数组如何处理这个:'np.ma.core.MaskedArray .__ eq__' – hpaulj

回答

1

根据suggestion by hpaulj我想通过查看np.ma.core.MaskedArray.__eq__来了解如何做到这一点。这是参考的最小实现。主要想法是在DerivedArray的基类的类型中以self的视图调用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)