diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/ma/core.py | 222 | ||||
-rw-r--r-- | numpy/ma/mrecords.py | 289 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 2425 | ||||
-rw-r--r-- | numpy/ma/tests/test_extras.py | 92 | ||||
-rw-r--r-- | numpy/ma/tests/test_mrecords.py | 61 |
5 files changed, 1708 insertions, 1381 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index e546e5bbe..392e91ec1 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -1196,7 +1196,7 @@ class MaskedArray(ndarray): DeprecationWarning) shrink = flag # Process data............ - _data = narray(data, dtype=dtype, copy=copy, subok=True, ndmin=ndmin) + _data = np.array(data, dtype=dtype, copy=copy, subok=True, ndmin=ndmin) _baseclass = getattr(data, '_baseclass', type(_data)) _basedict = getattr(data, '_basedict', getattr(data, '__dict__', {})) if not isinstance(data, MaskedArray) or not subok: @@ -1207,7 +1207,15 @@ class MaskedArray(ndarray): if hasattr(data,'_mask') and not isinstance(data, ndarray): _data._mask = data._mask _sharedmask = True - # Process mask ........... + # Process mask ............................... + # Number of named fields (or zero if none) + names_ = _data.dtype.names or () + # Type of the mask + if names_: + mdtype = [(n, MaskType) for n in names_] + else: + mdtype = MaskType + # Case 1. : no mask in input ............ if mask is nomask: # Erase the current mask ? if not keep_mask: @@ -1216,7 +1224,7 @@ class MaskedArray(ndarray): _data._mask = nomask # With full version else: - _data._mask = np.zeros(_data.shape, dtype=MaskType) + _data._mask = np.zeros(_data.shape, dtype=mdtype) if copy: _data._mask = _data._mask.copy() _data._sharedmask = False @@ -1224,7 +1232,14 @@ class MaskedArray(ndarray): _data._sharedmask = True # Case 2. : With a mask in input ........ else: - mask = np.array(mask, dtype=MaskType, copy=copy) + # Read the mask with the current mdtype + try: + mask = np.array(mask, copy=copy, dtype=mdtype) + # Or assume it's a sequence of bool/int + except TypeError: + mask = np.array([tuple([m]*len(mdtype)) for m in mask], + dtype=mdtype) + # Make sure the mask and the data have the same shape if mask.shape != _data.shape: (nd, nm) = (_data.size, mask.size) if nm == 1: @@ -1245,7 +1260,11 @@ class MaskedArray(ndarray): _data._mask = mask _data._sharedmask = not copy else: - _data._mask = umath.logical_or(mask, _data._mask) + if names_: + for n in names_: + _data._mask[n] |= mask[n] + else: + _data._mask = np.logical_or(mask, _data._mask) _data._sharedmask = False # Update fill_value....... if fill_value is None: @@ -1270,6 +1289,7 @@ class MaskedArray(ndarray): _dict = dict(_fill_value=getattr(obj, '_fill_value', None), _hardmask=getattr(obj, '_hardmask', False), _sharedmask=getattr(obj, '_sharedmask', False), + _isfield=getattr(obj, '_isfield', False), _baseclass=getattr(obj,'_baseclass', _baseclass), _basedict=_basedict,) self.__dict__.update(_dict) @@ -1379,12 +1399,11 @@ class MaskedArray(ndarray): if isinstance(indx, basestring): if self._fill_value is not None: dout._fill_value = self._fill_value[indx] + dout._isfield = True # Update the mask if needed if _mask is not nomask: - if isinstance(indx, basestring): - dout._mask = _mask.reshape(dout.shape) - else: - dout._mask = ndarray.__getitem__(_mask, indx).reshape(dout.shape) + dout._mask = _mask[indx] + dout._sharedmask = True # Note: Don't try to check for m.any(), that'll take too long... return dout #........................ @@ -1402,47 +1421,64 @@ class MaskedArray(ndarray): # msg = "Masked arrays must be filled before they can be used as indices!" # raise IndexError, msg if isinstance(indx, basestring): - ndarray.__setitem__(self._data, indx, getdata(value)) - warnings.warn("MaskedArray.__setitem__ on fields: "\ - "The mask is NOT affected!") + ndarray.__setitem__(self._data, indx, value) + ndarray.__setitem__(self._mask, indx, getmask(value)) return - #.... + #........................................ +# ndgetattr = ndarray.__getattribute__ + _names = ndarray.__getattribute__(self,'dtype').names or () + _data = self._data + _mask = ndarray.__getattribute__(self,'_mask') + #........................................ if value is masked: - m = self._mask - if m is nomask: - m = np.zeros(self.shape, dtype=MaskType) - m[indx] = True - self._mask = m - self._sharedmask = False + # The mask wasn't set: create a full version... + if _mask is nomask: + _mask = self._mask = make_mask_none(self.shape, _names) + # Now, set the mask to its value. + if _names: + _mask[indx] = tuple([True,] * len(_names)) + else: + _mask[indx] = True + if not self._isfield: + self._sharedmask = False return - #.... -# dval = np.array(value, copy=False, dtype=self.dtype) + #........................................ + # Get the _data part of the new value dval = value - mval = getmask(value) - if self._mask is nomask: + # Get the _mask part of the new value + mval = getattr(value, '_mask', nomask) + if _names and mval is nomask: + mval = tuple([False] * len(_names)) + if _mask is nomask: # Set the data, then the mask - ndarray.__setitem__(self._data,indx,dval) + ndarray.__setitem__(_data, indx, dval) if mval is not nomask: - self._mask = np.zeros(self.shape, dtype=MaskType) - self._mask[indx] = mval + _mask = self._mask = make_mask_none(self.shape, _names) + ndarray.__setitem__(_mask, indx, mval) elif not self._hardmask: # Unshare the mask if necessary to avoid propagation - self.unshare_mask() + if not self._isfield: + self.unshare_mask() + _mask = ndarray.__getattribute__(self,'_mask') # Set the data, then the mask - ndarray.__setitem__(self._data, indx, dval) - ndarray.__setitem__(self._mask, indx, mval) - elif hasattr(indx, 'dtype') and (indx.dtype==bool_): - indx = indx * umath.logical_not(self._mask) - ndarray.__setitem__(self._data, indx, dval) + ndarray.__setitem__(_data, indx, dval) + ndarray.__setitem__(_mask, indx, mval) + elif hasattr(indx, 'dtype') and (indx.dtype==MaskType): + indx = indx * umath.logical_not(_mask) + ndarray.__setitem__(_data,indx,dval) else: - mindx = mask_or(self._mask[indx], mval, copy=True) + if _names: + err_msg = "Flexible 'hard' masks are not yet supported..." + raise NotImplementedError(err_msg) + mindx = mask_or(_mask[indx], mval, copy=True) dindx = self._data[indx] if dindx.size > 1: dindx[~mindx] = dval elif mindx is nomask: dindx = dval - ndarray.__setitem__(self._data, indx, dindx) - self._mask[indx] = mindx + ndarray.__setitem__(_data, indx, dindx) + _mask[indx] = mindx + return #............................................ def __getslice__(self, i, j): """x.__getslice__(i, j) <==> x[i:j] @@ -1466,28 +1502,57 @@ class MaskedArray(ndarray): """Set the mask. """ - if mask is not nomask: - mask = narray(mask, copy=copy, dtype=MaskType) - # We could try to check whether shrinking is needed.. - # ... but we would waste some precious time -# if self._shrinkmask and not mask.any(): -# mask = nomask - if self._mask is nomask: - self._mask = mask - elif self._hardmask: - if mask is not nomask: - self._mask.__ior__(mask) - else: - # This one is tricky: if we set the mask that way, we may break the - # propagation. But if we don't, we end up with a mask full of False - # and a test on nomask fails... + names = ndarray.__getattribute__(self,'dtype').names + current_mask = ndarray.__getattribute__(self,'_mask') + if mask is masked: + mask = True + # Make sure the mask is set + if (current_mask is nomask): + # Just don't do anything is there's nothing to do... if mask is nomask: - self._mask = nomask + return + current_mask = self._mask = make_mask_none(self.shape, names) + # No named fields......... + if names is None: + # Hardmask: don't unmask the data + if self._hardmask: + current_mask |= mask + # Softmask: set everything to False else: - self.unshare_mask() - self._mask.flat = mask - if self._mask.shape: - self._mask = np.reshape(self._mask, self.shape) + current_mask.flat = mask + # Named fields w/ ............ + else: + mdtype = current_mask.dtype + mask = np.array(mask, copy=False) + # Mask is a singleton + if not mask.ndim: + # It's a boolean : make a record + if mask.dtype.kind == 'b': + mask = np.array(tuple([mask.item()]*len(mdtype)), + dtype=mdtype) + # It's a record: make sure the dtype is correct + else: + mask = mask.astype(mdtype) + # Mask is a sequence + else: + # Make sure the new mask is a ndarray with the proper dtype + try: + mask = np.array(mask, copy=copy, dtype=mdtype) + # Or assume it's a sequence of bool/int + except TypeError: + mask = np.array([tuple([m]*len(mdtype)) for m in mask], + dtype=mdtype) + # Hardmask: don't unmask the data + if self._hardmask: + for n in names: + current_mask[n] |= mask[n] + # Softmask: set everything to False + else: + current_mask.flat = mask + # Reshape if needed + if current_mask.shape: + current_mask.shape = self.shape + return _set_mask = __setmask__ #.... def _get_mask(self): @@ -1498,6 +1563,26 @@ class MaskedArray(ndarray): # return self._mask.reshape(self.shape) return self._mask mask = property(fget=_get_mask, fset=__setmask__, doc="Mask") + # + def _getrecordmask(self): + """Return the mask of the records. + A record is masked when all the fields are masked. + + """ + if self.dtype.names is None: + return self._mask + elif self.size > 1: + return self._mask.view((bool_, len(self.dtype))).all(1) + else: + return self._mask.view((bool_, len(self.dtype))).all() + + def _setrecordmask(self): + """Return the mask of the records. + A record is masked when all the fields are masked. + + """ + raise NotImplementedError("Coming soon: setting the mask per records!") + recordmask = property(fget=_getrecordmask) #............................................ def harden_mask(self): """Force the mask to hard. @@ -1602,14 +1687,22 @@ class MaskedArray(ndarray): """ m = self._mask - if m is nomask or not m.any(): + if m is nomask: return self._data # if fill_value is None: fill_value = self.fill_value # if self is masked_singleton: - result = np.asanyarray(fill_value) + return np.asanyarray(fill_value) + # + if len(self.dtype): + result = self._data.copy() + for n in result.dtype.names: + field = result[n] + np.putmask(field, self._mask[n], self.fill_value[n]) + elif not m.any(): + return self._data else: result = self._data.copy() try: @@ -1682,11 +1775,14 @@ class MaskedArray(ndarray): else: return str(self._data) # convert to object array to make filled work -#!!!: the two lines below seem more robust than the self._data.astype -# res = numeric.empty(self._data.shape, object_) -# numeric.putmask(res,~m,self._data) - res = self._data.astype("|O8") - res[m] = f + names = self.dtype.names + if names is None: + res = self._data.astype("|O8") + res[m] = f + else: + res = self._data.astype([(n,'|O8') for n in names]) + for field in names: + np.putmask(res[field], m[field], f) else: res = self.filled(self.fill_value) return str(res) @@ -3399,7 +3495,7 @@ def putmask(a, mask, values): #, mode='raise'): if getmask(a) is nomask: if valmask is not nomask: a._sharedmask = True - a.mask = np.zeros(a.shape, dtype=bool_) + a._mask = make_mask_none(a.shape, a.dtype.names) np.putmask(a._mask, mask, valmask) elif a._hardmask: if valmask is not nomask: diff --git a/numpy/ma/mrecords.py b/numpy/ma/mrecords.py index e25fb9b3e..ba4b0f915 100644 --- a/numpy/ma/mrecords.py +++ b/numpy/ma/mrecords.py @@ -72,7 +72,7 @@ If the argument `names` is not None, updates the field names to valid names. elif isinstance(names, str): new_names = names.split(',') else: - raise NameError, "illegal input names %s" % `names` + raise NameError("illegal input names %s" % `names`) nnames = len(new_names) if nnames < ndescr: new_names += default_names[nnames:] @@ -85,7 +85,7 @@ If the argument `names` is not None, updates the field names to valid names. ndescr.append(t) else: ndescr.append((n,t[1])) - return numeric.dtype(ndescr) + return np.dtype(ndescr) def _get_fieldmask(self): @@ -125,7 +125,7 @@ class MaskedRecords(MaskedArray, object): mdtype = [(k,'|b1') for (k,_) in self.dtype.descr] if mask is nomask or not np.size(mask): if not keep_mask: - self._fieldmask = tuple([False]*len(mdtype)) + self._mask = tuple([False]*len(mdtype)) else: mask = np.array(mask, copy=copy) if mask.shape != self.shape: @@ -144,79 +144,40 @@ class MaskedRecords(MaskedArray, object): self._sharedmask = True else: if mask.dtype == mdtype: - _fieldmask = mask + _mask = mask else: - _fieldmask = np.array([tuple([m]*len(mdtype)) for m in mask], - dtype=mdtype) - self._fieldmask = _fieldmask + _mask = np.array([tuple([m]*len(mdtype)) for m in mask], + dtype=mdtype) + self._mask = _mask return self #...................................................... def __array_finalize__(self,obj): + MaskedArray._update_from(self,obj) # Make sure we have a _fieldmask by default .. _fieldmask = getattr(obj, '_fieldmask', None) if _fieldmask is None: mdescr = [(n,'|b1') for (n,_) in self.dtype.descr] - _mask = getattr(obj, '_mask', nomask) - if _mask is nomask: - _fieldmask = np.empty(self.shape, dtype=mdescr).view(recarray) - _fieldmask.flat = tuple([False]*len(mdescr)) + objmask = getattr(obj, '_mask', nomask) + if objmask is nomask: + _mask = np.empty(self.shape, dtype=mdescr).view(recarray) + _mask.flat = tuple([False]*len(mdescr)) else: - _fieldmask = narray([tuple([m]*len(mdescr)) for m in _mask], - dtype=mdescr).view(recarray) - # Update some of the attributes - if obj is not None: - _baseclass = getattr(obj,'_baseclass',type(obj)) + _mask = narray([tuple([m]*len(mdescr)) for m in objmask], + dtype=mdescr).view(recarray) else: - _baseclass = recarray - attrdict = dict(_fieldmask=_fieldmask, - _hardmask=getattr(obj,'_hardmask',False), - _fill_value=getattr(obj,'_fill_value',None), - _sharedmask=getattr(obj,'_sharedmask',False), - _baseclass=_baseclass) - self.__dict__.update(attrdict) - # Finalize as a regular maskedarray ..... - # Update special attributes ... - self._basedict = getattr(obj, '_basedict', getattr(obj,'__dict__',{})) - self.__dict__.update(self._basedict) + _mask = _fieldmask + # Update some of the attributes + _locdict = self.__dict__ + if _locdict['_baseclass'] == ndarray: + _locdict['_baseclass'] = recarray + _locdict.update(_mask=_mask, _fieldmask=_mask) return - #...................................................... + def _getdata(self): "Returns the data as a recarray." return ndarray.view(self,recarray) _data = property(fget=_getdata) - #...................................................... - def __setmask__(self, mask): - "Sets the mask and update the fieldmask." - names = self.dtype.names - fmask = self.__dict__['_fieldmask'] - # - if isinstance(mask,ndarray) and mask.dtype.names == names: - for n in names: - fmask[n] = mask[n].astype(bool) -# self.__dict__['_fieldmask'] = fmask.view(recarray) - return - newmask = make_mask(mask, copy=False) - if names is not None: - if self._hardmask: - for n in names: - fmask[n].__ior__(newmask) - else: - for n in names: - fmask[n].flat = newmask - return - _setmask = __setmask__ - # - def _getmask(self): - """Return the mask of the mrecord. - A record is masked when all the fields are masked. - """ - if self.size > 1: - return self._fieldmask.view((bool_, len(self.dtype))).all(1) - else: - return self._fieldmask.view((bool_, len(self.dtype))).all() - mask = _mask = property(fget=_getmask, fset=_setmask) - #...................................................... def __len__(self): "Returns the length" # We have more than one record @@ -224,88 +185,104 @@ class MaskedRecords(MaskedArray, object): return len(self._data) # We have only one record: return the nb of fields return len(self.dtype) - #...................................................... + def __getattribute__(self, attr): - "Returns the given attribute." try: - # Returns a generic attribute - return object.__getattribute__(self,attr) - except AttributeError: - # OK, so attr must be a field name + return object.__getattribute__(self, attr) + except AttributeError: # attr must be a fieldname pass - # Get the list of fields ...... - _names = self.dtype.names - if attr in _names: - _data = self._data - _mask = self._fieldmask -# obj = masked_array(_data.__getattribute__(attr), copy=False, -# mask=_mask.__getattribute__(attr)) - # Use a view in order to avoid the copy of the mask in MaskedArray.__new__ - obj = narray(_data.__getattribute__(attr), copy=False).view(MaskedArray) - obj._mask = _mask.__getattribute__(attr) - if not obj.ndim and obj._mask: - return masked - return obj - raise AttributeError,"No attribute '%s' !" % attr + fielddict = ndarray.__getattribute__(self,'dtype').fields + try: + res = fielddict[attr][:2] + except (TypeError, KeyError): + raise AttributeError, "record array has no attribute %s" % attr + # So far, so good... + _localdict = ndarray.__getattribute__(self,'__dict__') + _data = ndarray.view(self, _localdict['_baseclass']) + obj = _data.getfield(*res) + if obj.dtype.fields: + raise NotImplementedError("MaskedRecords is currently limited to"\ + "simple records...") + obj = obj.view(MaskedArray) + obj._baseclass = ndarray + obj._isfield = True + # Get some special attributes + _fill_value = _localdict.get('_fill_value', None) + _mask = _localdict.get('_mask', None) + # Reset the object's mask + if _mask is not None: + try: + obj._mask = _mask[attr] + except IndexError: + # Couldn't find a mask: use the default (nomask) + pass + # Reset the field values + if _fill_value is not None: + try: + obj._fill_value = _fill_value[attr] + except ValueError: + obj._fill_value = None + return obj + def __setattr__(self, attr, val): "Sets the attribute attr to the value val." -# newattr = attr not in self.__dict__ + # Should we call __setmask__ first ? + if attr in ['_mask','mask','_fieldmask','fieldmask']: + self.__setmask__(val) + return + # Create a shortcut (so that we don't have to call getattr all the time) + _localdict = self.__dict__ + # Check whether we're creating a new field + newattr = attr not in _localdict try: # Is attr a generic attribute ? ret = object.__setattr__(self, attr, val) except: # Not a generic attribute: exit if it's not a valid field - fielddict = self.dtype.names or {} + fielddict = ndarray.__getattribute__(self,'dtype').fields or {} if attr not in fielddict: exctype, value = sys.exc_info()[:2] raise exctype, value else: - if attr in ['_mask','fieldmask']: - self.__setmask__(val) - return # Get the list of names ...... - _names = self.dtype.names - if _names is None: - _names = [] - else: - _names = list(_names) + fielddict = ndarray.__getattribute__(self,'dtype').fields or {} # Check the attribute - self_dict = self.__dict__ - if attr not in _names+list(self_dict): +##### _localdict = self.__dict__ + if attr not in fielddict: return ret - if attr not in self_dict: # We just added this one + if newattr: # We just added this one try: # or this setattr worked on an internal # attribute. object.__delattr__(self, attr) except: return ret - # Case #1.: Basic field ............ - base_fmask = self._fieldmask - _names = self.dtype.names or [] - _localdict = self.__dict__ - if attr in _names: - if val is masked: - _fill_value = _localdict['_fill_value'] - if _fill_value is not None: - fval = _fill_value[attr] - else: - fval = None - mval = True + # Let's try to set the field + try: + res = fielddict[attr][:2] + except (TypeError,KeyError): + raise AttributeError, "record array has no attribute %s" % attr + # + if val is masked: + _fill_value = _localdict['_fill_value'] + if _fill_value is not None: + dval = _localdict['_fill_value'][attr] else: - fval = filled(val) - mval = getmaskarray(val) - if self._hardmask: - mval = mask_or(mval, base_fmask.__getattr__(attr)) - self._data.__setattr__(attr, fval) - base_fmask.__setattr__(attr, mval) - return - #............................................ + dval = val + mval = True + else: + dval = filled(val) + mval = getmaskarray(val) + obj = ndarray.__getattribute__(self,'_data').setfield(dval, *res) + _localdict['_mask'].__setitem__(attr, mval) + return obj + + def __getitem__(self, indx): """Returns all the fields sharing the same fieldname base. The fieldname base is either `_data` or `_mask`.""" _localdict = self.__dict__ - _fieldmask = _localdict['_fieldmask'] + _mask = _localdict['_fieldmask'] _data = self._data # We want a field ........ if isinstance(indx, basestring): @@ -314,7 +291,7 @@ The fieldname base is either `_data` or `_mask`.""" #!!!: ...that break propagation #!!!: Don't force the mask to nomask, that wrecks easy masking obj = _data[indx].view(MaskedArray) - obj._mask = _fieldmask[indx] + obj._mask = _mask[indx] obj._sharedmask = True fval = _localdict['_fill_value'] if fval is not None: @@ -325,47 +302,17 @@ The fieldname base is either `_data` or `_mask`.""" return obj # We want some elements .. # First, the data ........ - obj = narray(_data[indx], copy=False).view(mrecarray) - obj._fieldmask = narray(_fieldmask[indx], copy=False).view(recarray) + obj = np.array(_data[indx], copy=False).view(mrecarray) + obj._mask = np.array(_mask[indx], copy=False).view(recarray) return obj #.... def __setitem__(self, indx, value): "Sets the given record to value." MaskedArray.__setitem__(self, indx, value) if isinstance(indx, basestring): - self._fieldmask[indx] = ma.getmaskarray(value) + self._mask[indx] = ma.getmaskarray(value) + - #............................................ - def __setslice__(self, i, j, value): - "Sets the slice described by [i,j] to `value`." - _localdict = self.__dict__ - d = self._data - m = _localdict['_fieldmask'] - names = self.dtype.names - if value is masked: - for n in names: - m[i:j][n] = True - elif not self._hardmask: - fval = filled(value) - mval = getmaskarray(value) - for n in names: - d[n][i:j] = fval - m[n][i:j] = mval - else: - mindx = getmaskarray(self)[i:j] - dval = np.asarray(value) - valmask = getmask(value) - if valmask is nomask: - for n in names: - mval = mask_or(m[n][i:j], valmask) - d[n][i:j][~mval] = value - elif valmask.size > 1: - for n in names: - mval = mask_or(m[n][i:j], valmask) - d[n][i:j][~mval] = dval[~mval] - m[n][i:j] = mask_or(m[n][i:j], mval) - self._fieldmask = m - #...................................................... def __str__(self): "Calculates the string representation." if self.size > 1: @@ -394,55 +341,25 @@ The fieldname base is either `_data` or `_mask`.""" return ndarray.view(self, obj) except TypeError: pass - dtype = np.dtype(obj) - if dtype.fields is None: - return self.__array__().view(dtype) + dtype_ = np.dtype(obj) + if dtype_.fields is None: + return self.__array__().view(dtype_) return ndarray.view(self, obj) - #...................................................... - def filled(self, fill_value=None): - """Returns an array of the same class as the _data part, where masked - values are filled with fill_value. - If fill_value is None, self.fill_value is used instead. - Subclassing is preserved. - - """ - _localdict = self.__dict__ - d = self._data - fm = _localdict['_fieldmask'] - if not np.asarray(fm, dtype=bool_).any(): - return d - # - if fill_value is None: - value = _check_fill_value(_localdict['_fill_value'], d.dtype) - else: - value = fill_value - if np.size(value) == 1: - value = np.array(tuple([value,] * len(d.dtype)), - dtype=d.dtype) - # - if self is masked: - result = np.asanyarray(value) - else: - result = d.copy() - for n in d.dtype.names: - np.putmask(np.asarray(result[n]), np.asarray(fm[n]), value[n]) - return result - #...................................................... def harden_mask(self): "Forces the mask to hard" self._hardmask = True def soften_mask(self): "Forces the mask to soft" self._hardmask = False - #...................................................... + def copy(self): """Returns a copy of the masked record.""" _localdict = self.__dict__ copied = self._data.copy().view(type(self)) copied._fieldmask = self._fieldmask.copy() return copied - #...................................................... + def tolist(self, fill_value=None): """Copy the data portion of the array to a hierarchical python list and returns that list. @@ -638,10 +555,10 @@ on the first line. An exception is raised if the file is 3D or more. # Start the conversion loop ....... for f in arr: try: - val = int(f) + int(f) except ValueError: try: - val = float(f) + float(f) except ValueError: try: val = complex(f) diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index f15f3751d..fd3395188 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -1,4 +1,4 @@ -# pylint: disable-msg=W0611, W0612, W0614, W0511,R0201 +# pylint: disable-msg=W0401,W0511,W0611,W0612,W0614,R0201,E1102 """Tests suite for MaskedArray & subclassing. :author: Pierre Gerard-Marchant @@ -9,47 +9,77 @@ __author__ = "Pierre GF Gerard-Marchant" import types import warnings -import numpy +import numpy as np import numpy.core.fromnumeric as fromnumeric +from numpy import ndarray + + from numpy.testing import NumpyTest, NumpyTestCase from numpy.testing import set_local_path, restore_path from numpy.testing.utils import build_err_msg -from numpy import array as narray import numpy.ma.testutils -from numpy.ma.testutils import * +from numpy.ma.testutils import NumpyTestCase, \ + assert_equal, assert_array_equal, fail_if_equal, assert_not_equal, \ + assert_almost_equal, assert_mask_equal, assert_equal_records import numpy.ma.core as coremodule from numpy.ma.core import * -pi = numpy.pi +pi = np.pi set_local_path() from test_old_ma import * restore_path() #.............................................................................. -class TestMA(NumpyTestCase): +class TestMaskedArray(NumpyTestCase): "Base test class for MaskedArrays." + def __init__(self, *args, **kwds): NumpyTestCase.__init__(self, *args, **kwds) self.setUp() def setUp (self): "Base data definition." - x = narray([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) - y = narray([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) a10 = 10. m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] xm = masked_array(x, mask=m1) ym = masked_array(y, mask=m2) - z = narray([-.5, 0., .5, .8]) + z = np.array([-.5, 0., .5, .8]) zm = masked_array(z, mask=[0,1,0,0]) - xf = numpy.where(m1, 1.e+20, x) + xf = np.where(m1, 1.e+20, x) xm.set_fill_value(1.e+20) self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf) - #........................ + + + def test_basicattributes(self): + "Tests some basic array attributes." + a = array([1,3,2]) + b = array([1,3,2], mask=[1,0,1]) + assert_equal(a.ndim, 1) + assert_equal(b.ndim, 1) + assert_equal(a.size, 3) + assert_equal(b.size, 3) + assert_equal(a.shape, (3,)) + assert_equal(b.shape, (3,)) + + + def test_basic0d(self): + "Checks masking a scalar" + x = masked_array(0) + assert_equal(str(x), '0') + x = masked_array(0,mask=True) + assert_equal(str(x), str(masked_print_option)) + x = masked_array(0, mask=False) + assert_equal(str(x), '0') + x = array(0, mask=1) + assert(x.filled().dtype is x.data.dtype) + + def test_basic1d(self): "Test of basic array creation and properties in 1 dimension." (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d @@ -58,7 +88,7 @@ class TestMA(NumpyTestCase): assert((xm-ym).filled(0).any()) fail_if_equal(xm.mask.astype(int_), ym.mask.astype(int_)) s = x.shape - assert_equal(numpy.shape(xm), s) + assert_equal(np.shape(xm), s) assert_equal(xm.shape, s) assert_equal(xm.dtype, x.dtype) assert_equal(zm.dtype, z.dtype) @@ -67,7 +97,8 @@ class TestMA(NumpyTestCase): assert_array_equal(xm, xf) assert_array_equal(filled(xm, 1.e20), xf) assert_array_equal(x, xm) - #........................ + + def test_basic2d(self): "Test of basic array creation and properties in 2 dimensions." (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d @@ -77,7 +108,7 @@ class TestMA(NumpyTestCase): xm.shape = s ym.shape = s xf.shape = s - + # assert(not isMaskedArray(x)) assert(isMaskedArray(xm)) assert_equal(shape(xm), s) @@ -87,308 +118,27 @@ class TestMA(NumpyTestCase): assert_equal(xm, xf) assert_equal(filled(xm, 1.e20), xf) assert_equal(x, xm) - #........................ - def test_basic_arithmetic (self): - "Test of basic arithmetic." - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - a2d = array([[1,2],[0,4]]) - a2dm = masked_array(a2d, [[0,0],[1,0]]) - assert_equal(a2d * a2d, a2d * a2dm) - assert_equal(a2d + a2d, a2d + a2dm) - assert_equal(a2d - a2d, a2d - a2dm) - for s in [(12,), (4,3), (2,6)]: - x = x.reshape(s) - y = y.reshape(s) - xm = xm.reshape(s) - ym = ym.reshape(s) - xf = xf.reshape(s) - assert_equal(-x, -xm) - assert_equal(x + y, xm + ym) - assert_equal(x - y, xm - ym) - assert_equal(x * y, xm * ym) - assert_equal(x / y, xm / ym) - assert_equal(a10 + y, a10 + ym) - assert_equal(a10 - y, a10 - ym) - assert_equal(a10 * y, a10 * ym) - assert_equal(a10 / y, a10 / ym) - assert_equal(x + a10, xm + a10) - assert_equal(x - a10, xm - a10) - assert_equal(x * a10, xm * a10) - assert_equal(x / a10, xm / a10) - assert_equal(x**2, xm**2) - assert_equal(abs(x)**2.5, abs(xm) **2.5) - assert_equal(x**y, xm**ym) - assert_equal(numpy.add(x,y), add(xm, ym)) - assert_equal(numpy.subtract(x,y), subtract(xm, ym)) - assert_equal(numpy.multiply(x,y), multiply(xm, ym)) - assert_equal(numpy.divide(x,y), divide(xm, ym)) - #........................ - def test_mixed_arithmetic(self): - "Tests mixed arithmetics." - na = narray([1]) - ma = array([1]) - self.failUnless(isinstance(na + ma, MaskedArray)) - self.failUnless(isinstance(ma + na, MaskedArray)) - #........................ - def test_inplace_arithmetic(self): - """Test of inplace operations and rich comparisons""" - # addition - x = arange(10) - y = arange(10) - xm = arange(10) - xm[2] = masked - x += 1 - assert_equal(x, y+1) - xm += 1 - assert_equal(xm, y+1) - # subtraction - x = arange(10) - xm = arange(10) - xm[2] = masked - x -= 1 - assert_equal(x, y-1) - xm -= 1 - assert_equal(xm, y-1) - # multiplication - x = arange(10)*1.0 - xm = arange(10)*1.0 - xm[2] = masked - x *= 2.0 - assert_equal(x, y*2) - xm *= 2.0 - assert_equal(xm, y*2) - # division - x = arange(10)*2 - xm = arange(10)*2 - xm[2] = masked - x /= 2 - assert_equal(x, y) - xm /= 2 - assert_equal(xm, y) - # division, pt 2 - x = arange(10)*1.0 - xm = arange(10)*1.0 - xm[2] = masked - x /= 2.0 - assert_equal(x, y/2.0) - xm /= arange(10) - assert_equal(xm, ones((10,))) - - warnings.simplefilter('ignore', DeprecationWarning) - x = arange(10).astype(float_) - xm = arange(10) - xm[2] = masked - id1 = x.raw_data().ctypes.data - x += 1. - assert (id1 == x.raw_data().ctypes.data) - assert_equal(x, y+1.) - warnings.simplefilter('default', DeprecationWarning) - - # addition w/ array - x = arange(10, dtype=float_) - xm = arange(10, dtype=float_) - xm[2] = masked - m = xm.mask - a = arange(10, dtype=float_) - a[-1] = masked - x += a - xm += a - assert_equal(x,y+a) - assert_equal(xm,y+a) - assert_equal(xm.mask, mask_or(m,a.mask)) - # subtraction w/ array - x = arange(10, dtype=float_) - xm = arange(10, dtype=float_) - xm[2] = masked - m = xm.mask - a = arange(10, dtype=float_) - a[-1] = masked - x -= a - xm -= a - assert_equal(x,y-a) - assert_equal(xm,y-a) - assert_equal(xm.mask, mask_or(m,a.mask)) - # multiplication w/ array - x = arange(10, dtype=float_) - xm = arange(10, dtype=float_) - xm[2] = masked - m = xm.mask - a = arange(10, dtype=float_) - a[-1] = masked - x *= a - xm *= a - assert_equal(x,y*a) - assert_equal(xm,y*a) - assert_equal(xm.mask, mask_or(m,a.mask)) - # division w/ array - x = arange(10, dtype=float_) - xm = arange(10, dtype=float_) - xm[2] = masked - m = xm.mask - a = arange(10, dtype=float_) - a[-1] = masked - x /= a - xm /= a - assert_equal(x,y/a) - assert_equal(xm,y/a) - assert_equal(xm.mask, mask_or(mask_or(m,a.mask), (a==0))) - # - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - z = xm/ym - assert_equal(z._mask, [1,1,1,0,0,1,1,0,0,0,1,1]) - assert_equal(z._data, [0.2,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.]) - xm = xm.copy() - xm /= ym - assert_equal(xm._mask, [1,1,1,0,0,1,1,0,0,0,1,1]) - assert_equal(xm._data, [1/5.,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.]) - def test_inplace_arithmetixx(self): - tiny = numpy.finfo(float).tiny - a = array([tiny, 1./tiny, 0.]) - assert_equal(getmaskarray(a/2), [0,0,0]) - assert_equal(getmaskarray(2/a), [1,0,1]) - - #.......................... - def test_scalararithmetic(self): - "Tests some scalar arithmetics on MaskedArrays." - xm = array(0, mask=1) - assert((1/array(0)).mask) - assert((1 + xm).mask) - assert((-xm).mask) - assert((-xm).mask) - assert(maximum(xm, xm).mask) - assert(minimum(xm, xm).mask) - assert(xm.filled().dtype is xm.data.dtype) - x = array(0, mask=0) - assert_equal(x.filled().ctypes.data, x.ctypes.data) - assert_equal(str(xm), str(masked_print_option)) - # Make sure we don't lose the shape in some circumstances - xm = array((0,0))/0. - assert_equal(xm.shape,(2,)) - assert_equal(xm.mask,[1,1]) - #......................... - def test_basic_ufuncs (self): - "Test various functions such as sin, cos." - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - assert_equal(numpy.cos(x), cos(xm)) - assert_equal(numpy.cosh(x), cosh(xm)) - assert_equal(numpy.sin(x), sin(xm)) - assert_equal(numpy.sinh(x), sinh(xm)) - assert_equal(numpy.tan(x), tan(xm)) - assert_equal(numpy.tanh(x), tanh(xm)) - assert_equal(numpy.sqrt(abs(x)), sqrt(xm)) - assert_equal(numpy.log(abs(x)), log(xm)) - assert_equal(numpy.log10(abs(x)), log10(xm)) - assert_equal(numpy.exp(x), exp(xm)) - assert_equal(numpy.arcsin(z), arcsin(zm)) - assert_equal(numpy.arccos(z), arccos(zm)) - assert_equal(numpy.arctan(z), arctan(zm)) - assert_equal(numpy.arctan2(x, y), arctan2(xm, ym)) - assert_equal(numpy.absolute(x), absolute(xm)) - assert_equal(numpy.equal(x,y), equal(xm, ym)) - assert_equal(numpy.not_equal(x,y), not_equal(xm, ym)) - assert_equal(numpy.less(x,y), less(xm, ym)) - assert_equal(numpy.greater(x,y), greater(xm, ym)) - assert_equal(numpy.less_equal(x,y), less_equal(xm, ym)) - assert_equal(numpy.greater_equal(x,y), greater_equal(xm, ym)) - assert_equal(numpy.conjugate(x), conjugate(xm)) - #........................ - def test_count_func (self): - "Tests count" - ott = array([0.,1.,2.,3.], mask=[1,0,0,0]) - assert( isinstance(count(ott), int)) - assert_equal(3, count(ott)) - assert_equal(1, count(1)) - assert_equal(0, array(1,mask=[1])) - ott = ott.reshape((2,2)) - assert isinstance(count(ott,0), ndarray) - assert isinstance(count(ott), types.IntType) - assert_equal(3, count(ott)) - assert getmask(count(ott,0)) is nomask - assert_equal([1,2],count(ott,0)) - #........................ - def test_minmax_func (self): - "Tests minimum and maximum." + def test_concatenate_basic(self): + "Tests concatenations." (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - xr = numpy.ravel(x) #max doesn't work if shaped - xmr = ravel(xm) - assert_equal(max(xr), maximum(xmr)) #true because of careful selection of data - assert_equal(min(xr), minimum(xmr)) #true because of careful selection of data - # - assert_equal(minimum([1,2,3],[4,0,9]), [1,0,3]) - assert_equal(maximum([1,2,3],[4,0,9]), [4,2,9]) - x = arange(5) - y = arange(5) - 2 - x[3] = masked - y[0] = masked - assert_equal(minimum(x,y), where(less(x,y), x, y)) - assert_equal(maximum(x,y), where(greater(x,y), x, y)) - assert minimum(x) == 0 - assert maximum(x) == 4 - # - x = arange(4).reshape(2,2) - x[-1,-1] = masked - assert_equal(maximum(x), 2) + # basic concatenation + assert_equal(np.concatenate((x,y)), concatenate((xm,ym))) + assert_equal(np.concatenate((x,y)), concatenate((x,y))) + assert_equal(np.concatenate((x,y)), concatenate((xm,y))) + assert_equal(np.concatenate((x,y,x)), concatenate((x,ym,x))) - def test_minmax_methods(self): - "Additional tests on max/min" - (_, _, _, _, _, xm, _, _, _, _) = self.d - xm.shape = (xm.size,) - assert_equal(xm.max(), 10) - assert(xm[0].max() is masked) - assert(xm[0].max(0) is masked) - assert(xm[0].max(-1) is masked) - assert_equal(xm.min(), -10.) - assert(xm[0].min() is masked) - assert(xm[0].min(0) is masked) - assert(xm[0].min(-1) is masked) - assert_equal(xm.ptp(), 20.) - assert(xm[0].ptp() is masked) - assert(xm[0].ptp(0) is masked) - assert(xm[0].ptp(-1) is masked) - # - x = array([1,2,3], mask=True) - assert(x.min() is masked) - assert(x.max() is masked) - assert(x.ptp() is masked) - #........................ - def test_addsumprod (self): - "Tests add, sum, product." - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - assert_equal(numpy.add.reduce(x), add.reduce(x)) - assert_equal(numpy.add.accumulate(x), add.accumulate(x)) - assert_equal(4, sum(array(4),axis=0)) - assert_equal(4, sum(array(4), axis=0)) - assert_equal(numpy.sum(x,axis=0), sum(x,axis=0)) - assert_equal(numpy.sum(filled(xm,0),axis=0), sum(xm,axis=0)) - assert_equal(numpy.sum(x,0), sum(x,0)) - assert_equal(numpy.product(x,axis=0), product(x,axis=0)) - assert_equal(numpy.product(x,0), product(x,0)) - assert_equal(numpy.product(filled(xm,1),axis=0), product(xm,axis=0)) - s = (3,4) - x.shape = y.shape = xm.shape = ym.shape = s - if len(s) > 1: - assert_equal(numpy.concatenate((x,y),1), concatenate((xm,ym),1)) - assert_equal(numpy.add.reduce(x,1), add.reduce(x,1)) - assert_equal(numpy.sum(x,1), sum(x,1)) - assert_equal(numpy.product(x,1), product(x,1)) - #......................... - def test_concat(self): + def test_concatenate_alongaxis(self): "Tests concatenations." (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - # basic concatenation - assert_equal(numpy.concatenate((x,y)), concatenate((xm,ym))) - assert_equal(numpy.concatenate((x,y)), concatenate((x,y))) - assert_equal(numpy.concatenate((x,y)), concatenate((xm,y))) - assert_equal(numpy.concatenate((x,y,x)), concatenate((x,ym,x))) # Concatenation along an axis s = (3,4) x.shape = y.shape = xm.shape = ym.shape = s - assert_equal(xm.mask, numpy.reshape(m1, s)) - assert_equal(ym.mask, numpy.reshape(m2, s)) + assert_equal(xm.mask, np.reshape(m1, s)) + assert_equal(ym.mask, np.reshape(m2, s)) xmym = concatenate((xm,ym),1) - assert_equal(numpy.concatenate((x,y),1), xmym) - assert_equal(numpy.concatenate((xm.mask,ym.mask),1), xmym._mask) + assert_equal(np.concatenate((x,y),1), xmym) + assert_equal(np.concatenate((xm.mask,ym.mask),1), xmym._mask) # x=zeros(2) y=array(ones(2),mask=[False,True]) @@ -399,16 +149,75 @@ class TestMA(NumpyTestCase): assert_array_equal(z,[1,1,0,0]) assert_array_equal(z.mask,[False,True,False,False]) - #........................ + def test_creation_ndmin(self): + "Check the use of ndmin" + x = array([1,2,3],mask=[1,0,0], ndmin=2) + assert_equal(x.shape,(1,3)) + assert_equal(x._data,[[1,2,3]]) + assert_equal(x._mask,[[1,0,0]]) + + def test_creation_maskcreation(self): + "Tests how masks are initialized at the creation of Maskedarrays." + data = arange(24, dtype=float_) + data[[3,6,15]] = masked + dma_1 = MaskedArray(data) + assert_equal(dma_1.mask, data.mask) + dma_2 = MaskedArray(dma_1) + assert_equal(dma_2.mask, dma_1.mask) + dma_3 = MaskedArray(dma_1, mask=[1,0,0,0]*6) + fail_if_equal(dma_3.mask, dma_1.mask) + + def test_asarray(self): + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + xm.fill_value = -9999 + xmm = asarray(xm) + assert_equal(xmm._data, xm._data) + assert_equal(xmm._mask, xm._mask) + assert_equal(xmm.fill_value, xm.fill_value) + + def test_fix_invalid(self): + "Checks fix_invalid." + data = masked_array(np.sqrt([-1., 0., 1.]), mask=[0,0,1]) + data_fixed = fix_invalid(data) + assert_equal(data_fixed._data, [data.fill_value, 0., 1.]) + assert_equal(data_fixed._mask, [1., 0., 1.]) + + def test_maskedelement(self): + "Test of masked element" + x = arange(6) + x[1] = masked + assert(str(masked) == '--') + assert(x[1] is masked) + assert_equal(filled(x[1], 0), 0) + # don't know why these should raise an exception... + #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, masked) + #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, 2) + #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, xx) + #self.failUnlessRaises(Exception, lambda x,y: x+y, xx, masked) + + def test_set_element_as_object(self): + """Tests setting elements with object""" + a = empty(1,dtype=object) + x = (1,2,3,4,5) + a[0] = x + assert_equal(a[0], x) + assert(a[0] is x) + # + import datetime + dt = datetime.datetime.now() + a[0] = dt + assert(a[0] is dt) + + def test_indexing(self): "Tests conversions and indexing" - x1 = numpy.array([1,2,4,3]) + x1 = np.array([1,2,4,3]) x2 = array(x1, mask=[1,0,0,0]) x3 = array(x1, mask=[0,1,0,1]) x4 = array(x1) # test conversion to strings junk, garbage = str(x2), repr(x2) - assert_equal(numpy.sort(x1),sort(x2,endwith=False)) + assert_equal(np.sort(x1),sort(x2,endwith=False)) # tests of indexing assert type(x2[1]) is type(x1[1]) assert x1[1] == x2[1] @@ -435,21 +244,22 @@ class TestMA(NumpyTestCase): x4[:] = masked_array([1,2,3,4],[0,1,1,0]) assert allequal(getmask(x4), array([0,1,1,0])) assert allequal(x4, array([1,2,3,4])) - x1 = numpy.arange(5)*1.0 + x1 = np.arange(5)*1.0 x2 = masked_values(x1, 3.0) assert_equal(x1,x2) assert allequal(array([0,0,0,1,0],MaskType), x2.mask) #FIXME: Well, eh, fill_value is now a property assert_equal(3.0, x2.fill_value()) assert_equal(3.0, x2.fill_value) x1 = array([1,'hello',2,3],object) - x2 = numpy.array([1,'hello',2,3],object) + x2 = np.array([1,'hello',2,3],object) s1 = x1[1] s2 = x2[1] assert_equal(type(s2), str) assert_equal(type(s1), str) assert_equal(s1, s2) assert x1[1:1].shape == (0,) - #........................ + + def test_copy(self): "Tests of some subtle points of copying and sizing." n = [0,0,1,0,0] @@ -460,7 +270,7 @@ class TestMA(NumpyTestCase): assert(m is not m3) warnings.simplefilter('ignore', DeprecationWarning) - x1 = numpy.arange(5) + x1 = np.arange(5) y1 = array(x1, mask=m) #assert( y1._data is x1) assert_equal(y1._data.__array_interface__, x1.__array_interface__) @@ -515,48 +325,56 @@ class TestMA(NumpyTestCase): y = masked_array(x, copy=True) assert_not_equal(y._data.ctypes.data, x._data.ctypes.data) assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data) - #........................ - def test_where(self): - "Test the where function" - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - d = where(xm>2,xm,-9) - assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.]) - assert_equal(d._mask, xm._mask) - d = where(xm>2,-9,ym) - assert_equal(d, [5.,0.,3., 2., -1.,-9.,-9., -10., -9., 1., 0., -9.]) - assert_equal(d._mask, [1,0,1,0,0,0,1,0,0,0,0,0]) - d = where(xm>2, xm, masked) - assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.]) - tmp = xm._mask.copy() - tmp[(xm<=2).filled(True)] = True - assert_equal(d._mask, tmp) + + + def test_pickling(self): + "Tests pickling" + import cPickle + a = arange(10) + a[::3] = masked + a.fill_value = 999 + a_pickled = cPickle.loads(a.dumps()) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled._data, a._data) + assert_equal(a_pickled.fill_value, 999) # - ixm = xm.astype(int_) - d = where(ixm>2, ixm, masked) - assert_equal(d, [-9,-9,-9,-9, -9, 4, -9, -9, 10, -9, -9, 3]) - assert_equal(d.dtype, ixm.dtype) + a = array(np.matrix(range(10)), mask=[1,0,1,0,0]*2) + a_pickled = cPickle.loads(a.dumps()) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled, a) + assert(isinstance(a_pickled._data,np.matrix)) + + + def test_single_element_subscript(self): + "Tests single element subscripts of Maskedarrays." + a = array([1,3,2]) + b = array([1,3,2], mask=[1,0,1]) + assert_equal(a[0].shape, ()) + assert_equal(b[0].shape, ()) + assert_equal(b[1].shape, ()) + + + def test_topython(self): + "Tests some communication issues with Python." + assert_equal(1, int(array(1))) + assert_equal(1.0, float(array(1))) + assert_equal(1, int(array([[[1]]]))) + assert_equal(1.0, float(array([[1]]))) + self.assertRaises(TypeError, float, array([1,1])) # - x = arange(10) - x[3] = masked - c = x >= 8 - z = where(c , x, masked) - assert z.dtype is x.dtype - assert z[3] is masked - assert z[4] is masked - assert z[7] is masked - assert z[8] is not masked - assert z[9] is not masked - assert_equal(x,z) + warnings.simplefilter('ignore',UserWarning) + assert np.isnan(float(array([1],mask=[1]))) + warnings.simplefilter('default',UserWarning) # - z = where(c , masked, x) - assert z.dtype is x.dtype - assert z[3] is masked - assert z[4] is not masked - assert z[7] is not masked - assert z[8] is masked - assert z[9] is masked + a = array([1,2,3],mask=[1,0,0]) + self.assertRaises(TypeError, lambda:float(a)) + assert_equal(float(a[-1]), 3.) + assert(np.isnan(float(a[0]))) + self.assertRaises(TypeError, int, a) + assert_equal(int(a[-1]), 3) + self.assertRaises(MAError, lambda:int(a[0])) + - #........................ def test_oddfeatures_1(self): "Test of other odd features" x = arange(20) @@ -568,7 +386,7 @@ class TestMA(NumpyTestCase): assert_equal(z.imag, 10*x) assert_equal((z*conjugate(z)).real, 101*x*x) z.imag[...] = 0.0 - + # x = arange(10) x[3] = masked assert str(x[3]) == str(masked) @@ -584,8 +402,8 @@ class TestMA(NumpyTestCase): assert z[8] is masked assert z[9] is masked assert_equal(x,z) - # - #........................ + + def test_oddfeatures_2(self): "Tests some more features." x = array([1.,2.,3.,4.,5.]) @@ -600,22 +418,8 @@ class TestMA(NumpyTestCase): assert z[1] is not masked assert z[2] is masked # - x = arange(6) - x[5] = masked - y = arange(6)*10 - y[2] = masked - c = array([1,1,1,0,0,0], mask=[1,0,0,0,0,0]) - cm = c.filled(1) - z = where(c,x,y) - zm = where(cm,x,y) - assert_equal(z, zm) - assert getmask(zm) is nomask - assert_equal(zm, [0,1,2,30,40,50]) - z = where(c, masked, 1) - assert_equal(z, [99,99,99,1,1,1]) - z = where(c, 1, masked) - assert_equal(z, [99, 1, 1, 99, 99, 99]) - #........................ + + def test_oddfeatures_3(self): """Tests some generic features.""" atest = array([10], mask=True) @@ -624,57 +428,251 @@ class TestMA(NumpyTestCase): atest[idx] = btest[idx] assert_equal(atest,[20]) #........................ - def test_oddfeatures_4(self): - """Tests some generic features.""" - atest = ones((10,10,10), dtype=float_) - btest = zeros(atest.shape, MaskType) - ctest = masked_where(btest,atest) - assert_equal(atest,ctest) - #........................ - def test_set_oddities(self): - """Tests setting elements with object""" - a = empty(1,dtype=object) - x = (1,2,3,4,5) - a[0] = x - assert_equal(a[0], x) - assert(a[0] is x) + +#------------------------------------------------------------------------------ + +class TestMaskedArrayArithmetic(NumpyTestCase): + "Base test class for MaskedArrays." + + def setUp (self): + "Base data definition." + x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + a10 = 10. + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + z = np.array([-.5, 0., .5, .8]) + zm = masked_array(z, mask=[0,1,0,0]) + xf = np.where(m1, 1.e+20, x) + xm.set_fill_value(1.e+20) + self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf) + + + def test_basic_arithmetic (self): + "Test of basic arithmetic." + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + a2d = array([[1,2],[0,4]]) + a2dm = masked_array(a2d, [[0,0],[1,0]]) + assert_equal(a2d * a2d, a2d * a2dm) + assert_equal(a2d + a2d, a2d + a2dm) + assert_equal(a2d - a2d, a2d - a2dm) + for s in [(12,), (4,3), (2,6)]: + x = x.reshape(s) + y = y.reshape(s) + xm = xm.reshape(s) + ym = ym.reshape(s) + xf = xf.reshape(s) + assert_equal(-x, -xm) + assert_equal(x + y, xm + ym) + assert_equal(x - y, xm - ym) + assert_equal(x * y, xm * ym) + assert_equal(x / y, xm / ym) + assert_equal(a10 + y, a10 + ym) + assert_equal(a10 - y, a10 - ym) + assert_equal(a10 * y, a10 * ym) + assert_equal(a10 / y, a10 / ym) + assert_equal(x + a10, xm + a10) + assert_equal(x - a10, xm - a10) + assert_equal(x * a10, xm * a10) + assert_equal(x / a10, xm / a10) + assert_equal(x**2, xm**2) + assert_equal(abs(x)**2.5, abs(xm) **2.5) + assert_equal(x**y, xm**ym) + assert_equal(np.add(x,y), add(xm, ym)) + assert_equal(np.subtract(x,y), subtract(xm, ym)) + assert_equal(np.multiply(x,y), multiply(xm, ym)) + assert_equal(np.divide(x,y), divide(xm, ym)) + + def test_mixed_arithmetic(self): + "Tests mixed arithmetics." + na = np.array([1]) + ma = array([1]) + self.failUnless(isinstance(na + ma, MaskedArray)) + self.failUnless(isinstance(ma + na, MaskedArray)) + + + def test_limits_arithmetic(self): + tiny = np.finfo(float).tiny + a = array([tiny, 1./tiny, 0.]) + assert_equal(getmaskarray(a/2), [0,0,0]) + assert_equal(getmaskarray(2/a), [1,0,1]) + + def test_masked_singleton_arithmetic(self): + "Tests some scalar arithmetics on MaskedArrays." + # Masked singleton should remain masked no matter what + xm = array(0, mask=1) + assert((1/array(0)).mask) + assert((1 + xm).mask) + assert((-xm).mask) + assert(maximum(xm, xm).mask) + assert(minimum(xm, xm).mask) + + def test_arithmetic_with_masked_singleton(self): + "Checks that there's no collapsing to masked" + x = masked_array([1,2]) + y = x * masked + assert_equal(y.shape, x.shape) + assert_equal(y._mask, [True, True]) + y = x[0] * masked + assert y is masked + y = x + masked + assert_equal(y.shape, x.shape) + assert_equal(y._mask, [True, True]) + + + + def test_scalar_arithmetic(self): + x = array(0, mask=0) + assert_equal(x.filled().ctypes.data, x.ctypes.data) + # Make sure we don't lose the shape in some circumstances + xm = array((0,0))/0. + assert_equal(xm.shape,(2,)) + assert_equal(xm.mask,[1,1]) + + def test_basic_ufuncs (self): + "Test various functions such as sin, cos." + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + assert_equal(np.cos(x), cos(xm)) + assert_equal(np.cosh(x), cosh(xm)) + assert_equal(np.sin(x), sin(xm)) + assert_equal(np.sinh(x), sinh(xm)) + assert_equal(np.tan(x), tan(xm)) + assert_equal(np.tanh(x), tanh(xm)) + assert_equal(np.sqrt(abs(x)), sqrt(xm)) + assert_equal(np.log(abs(x)), log(xm)) + assert_equal(np.log10(abs(x)), log10(xm)) + assert_equal(np.exp(x), exp(xm)) + assert_equal(np.arcsin(z), arcsin(zm)) + assert_equal(np.arccos(z), arccos(zm)) + assert_equal(np.arctan(z), arctan(zm)) + assert_equal(np.arctan2(x, y), arctan2(xm, ym)) + assert_equal(np.absolute(x), absolute(xm)) + assert_equal(np.equal(x,y), equal(xm, ym)) + assert_equal(np.not_equal(x,y), not_equal(xm, ym)) + assert_equal(np.less(x,y), less(xm, ym)) + assert_equal(np.greater(x,y), greater(xm, ym)) + assert_equal(np.less_equal(x,y), less_equal(xm, ym)) + assert_equal(np.greater_equal(x,y), greater_equal(xm, ym)) + assert_equal(np.conjugate(x), conjugate(xm)) + + + def test_count_func (self): + "Tests count" + ott = array([0.,1.,2.,3.], mask=[1,0,0,0]) + assert( isinstance(count(ott), int)) + assert_equal(3, count(ott)) + assert_equal(1, count(1)) + assert_equal(0, array(1,mask=[1])) + ott = ott.reshape((2,2)) + assert isinstance(count(ott,0), ndarray) + assert isinstance(count(ott), types.IntType) + assert_equal(3, count(ott)) + assert getmask(count(ott,0)) is nomask + assert_equal([1,2],count(ott,0)) + + def test_minmax_func (self): + "Tests minimum and maximum." + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + xr = np.ravel(x) #max doesn't work if shaped + xmr = ravel(xm) + assert_equal(max(xr), maximum(xmr)) #true because of careful selection of data + assert_equal(min(xr), minimum(xmr)) #true because of careful selection of data # - import datetime - dt = datetime.datetime.now() - a[0] = dt - assert(a[0] is dt) - #........................ - def test_maskingfunctions(self): - "Tests masking functions." - x = array([1.,2.,3.,4.,5.]) - x[2] = masked - assert_equal(masked_where(greater(x, 2), x), masked_greater(x,2)) - assert_equal(masked_where(greater_equal(x, 2), x), masked_greater_equal(x,2)) - assert_equal(masked_where(less(x, 2), x), masked_less(x,2)) - assert_equal(masked_where(less_equal(x, 2), x), masked_less_equal(x,2)) - assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x,2)) - assert_equal(masked_where(equal(x, 2), x), masked_equal(x,2)) - assert_equal(masked_where(not_equal(x,2), x), masked_not_equal(x,2)) - assert_equal(masked_inside(range(5), 1, 3), [0, 199, 199, 199, 4]) - assert_equal(masked_outside(range(5), 1, 3),[199,1,2,3,199]) - assert_equal(masked_inside(array(range(5), mask=[1,0,0,0,0]), 1, 3).mask, [1,1,1,1,0]) - assert_equal(masked_outside(array(range(5), mask=[0,1,0,0,0]), 1, 3).mask, [1,1,0,0,1]) - assert_equal(masked_equal(array(range(5), mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,0]) - assert_equal(masked_not_equal(array([2,2,1,2,1], mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,1]) - assert_equal(masked_where([1,1,0,0,0], [1,2,3,4,5]), [99,99,3,4,5]) + assert_equal(minimum([1,2,3],[4,0,9]), [1,0,3]) + assert_equal(maximum([1,2,3],[4,0,9]), [4,2,9]) + x = arange(5) + y = arange(5) - 2 + x[3] = masked + y[0] = masked + assert_equal(minimum(x,y), where(less(x,y), x, y)) + assert_equal(maximum(x,y), where(greater(x,y), x, y)) + assert minimum(x) == 0 + assert maximum(x) == 4 + # + x = arange(4).reshape(2,2) + x[-1,-1] = masked + assert_equal(maximum(x), 2) + + + def test_minmax_funcs_with_output(self): + "Tests the min/max functions with explicit outputs" + mask = np.random.rand(12).round() + xm = array(np.random.uniform(0,10,12),mask=mask) + xm.shape = (3,4) + for funcname in ('min', 'max'): + # Initialize + npfunc = getattr(np, funcname) + mafunc = getattr(coremodule, funcname) + # Use the np version + nout = np.empty((4,), dtype=int) + result = npfunc(xm,axis=0,out=nout) + assert(result is nout) + # Use the ma version + nout.fill(-999) + result = mafunc(xm,axis=0,out=nout) + assert(result is nout) + + + def test_minmax_methods(self): + "Additional tests on max/min" + (_, _, _, _, _, xm, _, _, _, _) = self.d + xm.shape = (xm.size,) + assert_equal(xm.max(), 10) + assert(xm[0].max() is masked) + assert(xm[0].max(0) is masked) + assert(xm[0].max(-1) is masked) + assert_equal(xm.min(), -10.) + assert(xm[0].min() is masked) + assert(xm[0].min(0) is masked) + assert(xm[0].min(-1) is masked) + assert_equal(xm.ptp(), 20.) + assert(xm[0].ptp() is masked) + assert(xm[0].ptp(0) is masked) + assert(xm[0].ptp(-1) is masked) + # + x = array([1,2,3], mask=True) + assert(x.min() is masked) + assert(x.max() is masked) + assert(x.ptp() is masked) #........................ + def test_addsumprod (self): + "Tests add, sum, product." + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + assert_equal(np.add.reduce(x), add.reduce(x)) + assert_equal(np.add.accumulate(x), add.accumulate(x)) + assert_equal(4, sum(array(4),axis=0)) + assert_equal(4, sum(array(4), axis=0)) + assert_equal(np.sum(x,axis=0), sum(x,axis=0)) + assert_equal(np.sum(filled(xm,0),axis=0), sum(xm,axis=0)) + assert_equal(np.sum(x,0), sum(x,0)) + assert_equal(np.product(x,axis=0), product(x,axis=0)) + assert_equal(np.product(x,0), product(x,0)) + assert_equal(np.product(filled(xm,1),axis=0), product(xm,axis=0)) + s = (3,4) + x.shape = y.shape = xm.shape = ym.shape = s + if len(s) > 1: + assert_equal(np.concatenate((x,y),1), concatenate((xm,ym),1)) + assert_equal(np.add.reduce(x,1), add.reduce(x,1)) + assert_equal(np.sum(x,1), sum(x,1)) + assert_equal(np.product(x,1), product(x,1)) + + + + def test_TakeTransposeInnerOuter(self): "Test of take, transpose, inner, outer products" x = arange(24) - y = numpy.arange(24) + y = np.arange(24) x[5:6] = masked x = x.reshape(2,3,4) y = y.reshape(2,3,4) - assert_equal(numpy.transpose(y,(2,0,1)), transpose(x,(2,0,1))) - assert_equal(numpy.take(y, (2,0,1), 1), take(x, (2,0,1), 1)) - assert_equal(numpy.inner(filled(x,0),filled(y,0)), + assert_equal(np.transpose(y,(2,0,1)), transpose(x,(2,0,1))) + assert_equal(np.take(y, (2,0,1), 1), take(x, (2,0,1), 1)) + assert_equal(np.inner(filled(x,0),filled(y,0)), inner(x, y)) - assert_equal(numpy.outer(filled(x,0),filled(y,0)), + assert_equal(np.outer(filled(x,0),filled(y,0)), outer(x, y)) y = array(['abc', 1, 'def', 2, 3], object) y[2] = masked @@ -682,166 +680,8 @@ class TestMA(NumpyTestCase): assert t[0] == 'abc' assert t[1] == 2 assert t[2] == 3 - #....................... - def test_maskedelement(self): - "Test of masked element" - x = arange(6) - x[1] = masked - assert(str(masked) == '--') - assert(x[1] is masked) - assert_equal(filled(x[1], 0), 0) - # don't know why these should raise an exception... - #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, masked) - #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, 2) - #self.failUnlessRaises(Exception, lambda x,y: x+y, masked, xx) - #self.failUnlessRaises(Exception, lambda x,y: x+y, xx, masked) - #........................ - def test_scalar(self): - "Checks masking a scalar" - x = masked_array(0) - assert_equal(str(x), '0') - x = masked_array(0,mask=True) - assert_equal(str(x), str(masked_print_option)) - x = masked_array(0, mask=False) - assert_equal(str(x), '0') - #........................ - def test_usingmasked(self): - "Checks that there's no collapsing to masked" - x = masked_array([1,2]) - y = x * masked - assert_equal(y.shape, x.shape) - assert_equal(y._mask, [True, True]) - y = x[0] * masked - assert y is masked - y = x + masked - assert_equal(y.shape, x.shape) - assert_equal(y._mask, [True, True]) - #........................ - def test_topython(self): - "Tests some communication issues with Python." - assert_equal(1, int(array(1))) - assert_equal(1.0, float(array(1))) - assert_equal(1, int(array([[[1]]]))) - assert_equal(1.0, float(array([[1]]))) - self.assertRaises(TypeError, float, array([1,1])) - warnings.simplefilter('ignore',UserWarning) - assert numpy.isnan(float(array([1],mask=[1]))) - warnings.simplefilter('default',UserWarning) - # - a = array([1,2,3],mask=[1,0,0]) - self.assertRaises(TypeError, lambda:float(a)) - assert_equal(float(a[-1]), 3.) - assert(numpy.isnan(float(a[0]))) - self.assertRaises(TypeError, int, a) - assert_equal(int(a[-1]), 3) - self.assertRaises(MAError, lambda:int(a[0])) - #........................ - def test_arraymethods(self): - "Tests some MaskedArray methods." - a = array([1,3,2]) - b = array([1,3,2], mask=[1,0,1]) - assert_equal(a.any(), a.data.any()) - assert_equal(a.all(), a.data.all()) - assert_equal(a.argmax(), a.data.argmax()) - assert_equal(a.argmin(), a.data.argmin()) - assert_equal(a.choose(0,1,2,3,4), a.data.choose(0,1,2,3,4)) - assert_equal(a.compress([1,0,1]), a.data.compress([1,0,1])) - assert_equal(a.conj(), a.data.conj()) - assert_equal(a.conjugate(), a.data.conjugate()) - # - m = array([[1,2],[3,4]]) - assert_equal(m.diagonal(), m.data.diagonal()) - assert_equal(a.sum(), a.data.sum()) - assert_equal(a.take([1,2]), a.data.take([1,2])) - assert_equal(m.transpose(), m.data.transpose()) - #........................ - def test_basicattributes(self): - "Tests some basic array attributes." - a = array([1,3,2]) - b = array([1,3,2], mask=[1,0,1]) - assert_equal(a.ndim, 1) - assert_equal(b.ndim, 1) - assert_equal(a.size, 3) - assert_equal(b.size, 3) - assert_equal(a.shape, (3,)) - assert_equal(b.shape, (3,)) - #........................ - def test_single_element_subscript(self): - "Tests single element subscripts of Maskedarrays." - a = array([1,3,2]) - b = array([1,3,2], mask=[1,0,1]) - assert_equal(a[0].shape, ()) - assert_equal(b[0].shape, ()) - assert_equal(b[1].shape, ()) - #........................ - def test_maskcreation(self): - "Tests how masks are initialized at the creation of Maskedarrays." - data = arange(24, dtype=float_) - data[[3,6,15]] = masked - dma_1 = MaskedArray(data) - assert_equal(dma_1.mask, data.mask) - dma_2 = MaskedArray(dma_1) - assert_equal(dma_2.mask, dma_1.mask) - dma_3 = MaskedArray(dma_1, mask=[1,0,0,0]*6) - fail_if_equal(dma_3.mask, dma_1.mask) - - def test_pickling(self): - "Tests pickling" - import cPickle - a = arange(10) - a[::3] = masked - a.fill_value = 999 - a_pickled = cPickle.loads(a.dumps()) - assert_equal(a_pickled._mask, a._mask) - assert_equal(a_pickled._data, a._data) - assert_equal(a_pickled.fill_value, 999) - # - a = array(numpy.matrix(range(10)), mask=[1,0,1,0,0]*2) - a_pickled = cPickle.loads(a.dumps()) - assert_equal(a_pickled._mask, a._mask) - assert_equal(a_pickled, a) - assert(isinstance(a_pickled._data,numpy.matrix)) - # - def test_fillvalue(self): - "Having fun with the fill_value" - data = masked_array([1,2,3],fill_value=-999) - series = data[[0,2,1]] - assert_equal(series._fill_value, data._fill_value) - # - mtype = [('f',float_),('s','|S3')] - x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype) - x.fill_value=999 - assert_equal(x.fill_value.item(),[999.,'999']) - assert_equal(x['f'].fill_value, 999) - assert_equal(x['s'].fill_value, '999') - # - x.fill_value=(9,'???') - assert_equal(x.fill_value.item(), (9,'???')) - assert_equal(x['f'].fill_value, 9) - assert_equal(x['s'].fill_value, '???') - # - x = array([1,2,3.1]) - x.fill_value = 999 - assert_equal(numpy.asarray(x.fill_value).dtype, float_) - assert_equal(x.fill_value, 999.) - # - def test_asarray(self): - (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d - xm.fill_value = -9999 - xmm = asarray(xm) - assert_equal(xmm._data, xm._data) - assert_equal(xmm._mask, xm._mask) - assert_equal(xmm.fill_value, xm.fill_value) - # - def test_fix_invalid(self): - "Checks fix_invalid." - data = masked_array(numpy.sqrt([-1., 0., 1.]), mask=[0,0,1]) - data_fixed = fix_invalid(data) - assert_equal(data_fixed._data, [data.fill_value, 0., 1.]) - assert_equal(data_fixed._mask, [1., 0., 1.]) - # def test_imag_real(self): "Check complex" xx = array([1+10j,20+2j], mask=[1,0]) @@ -851,42 +691,136 @@ class TestMA(NumpyTestCase): assert_equal(xx.real,[1,20]) assert_equal(xx.real.filled(), [1e+20,20]) assert_equal(xx.real.dtype, xx._data.real.dtype) - # - def test_ndmin(self): - "Check the use of ndmin" - x = array([1,2,3],mask=[1,0,0], ndmin=2) - assert_equal(x.shape,(1,3)) - assert_equal(x._data,[[1,2,3]]) - assert_equal(x._mask,[[1,0,0]]) - # - def test_record(self): - "Check record access" - mtype = [('f',float_),('s','|S3')] - x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype) - x[1] = masked + + + def test_methods_with_output(self): + xm = array(np.random.uniform(0,10,12)).reshape(3,4) + xm[:,0] = xm[0] = xm[-1,-1] = masked # - (xf, xs) = (x['f'], x['s']) - assert_equal(xf.data, [1,2,numpy.pi]) - assert_equal(xf.mask, [0,1,0]) - assert_equal(xf.dtype, float_) - assert_equal(xs.data, ['a', 'b', 'pi']) - assert_equal(xs.mask, [0,1,0]) - assert_equal(xs.dtype, '|S3') - # - def test_set_records(self): - "Check setting an element of a record)" - mtype = [('f',float_),('s','|S3')] - x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype) - x[0] = (10,'A') - (xf, xs) = (x['f'], x['s']) - assert_equal(xf.data, [10,2,numpy.pi]) - assert_equal(xf.dtype, float_) - assert_equal(xs.data, ['A', 'b', 'pi']) - assert_equal(xs.dtype, '|S3') + funclist = ('sum','prod','var','std', 'max', 'min', 'ptp', 'mean',) + # + for funcname in funclist: + npfunc = getattr(np, funcname) + xmmeth = getattr(xm, funcname) + + # A ndarray as explicit input + output = np.empty(4, dtype=float) + output.fill(-9999) + result = npfunc(xm, axis=0,out=output) + # ... the result should be the given output + assert(result is output) + assert_equal(result, xmmeth(axis=0, out=output)) + # + output = empty(4, dtype=int) + result = xmmeth(axis=0, out=output) + assert(result is output) + assert(output[0] is masked) + +#------------------------------------------------------------------------------ + +class TestMaskedArrayAttributes(NumpyTestCase): + + + def test_keepmask(self): + "Tests the keep mask flag" + x = masked_array([1,2,3], mask=[1,0,0]) + mx = masked_array(x) + assert_equal(mx.mask, x.mask) + mx = masked_array(x, mask=[0,1,0], keep_mask=False) + assert_equal(mx.mask, [0,1,0]) + mx = masked_array(x, mask=[0,1,0], keep_mask=True) + assert_equal(mx.mask, [1,1,0]) + # We default to true + mx = masked_array(x, mask=[0,1,0]) + assert_equal(mx.mask, [1,1,0]) + + def test_hardmask(self): + "Test hard_mask" + d = arange(5) + n = [0,0,0,1,1] + m = make_mask(n) + xh = array(d, mask = m, hard_mask=True) + # We need to copy, to avoid updating d in xh! + xs = array(d, mask = m, hard_mask=False, copy=True) + xh[[1,4]] = [10,40] + xs[[1,4]] = [10,40] + assert_equal(xh._data, [0,10,2,3,4]) + assert_equal(xs._data, [0,10,2,3,40]) + #assert_equal(xh.mask.ctypes.data, m.ctypes.data) + assert_equal(xs.mask, [0,0,0,1,0]) + assert(xh._hardmask) + assert(not xs._hardmask) + xh[1:4] = [10,20,30] + xs[1:4] = [10,20,30] + assert_equal(xh._data, [0,10,20,3,4]) + assert_equal(xs._data, [0,10,20,30,40]) + #assert_equal(xh.mask.ctypes.data, m.ctypes.data) + assert_equal(xs.mask, nomask) + xh[0] = masked + xs[0] = masked + assert_equal(xh.mask, [1,0,0,1,1]) + assert_equal(xs.mask, [1,0,0,0,0]) + xh[:] = 1 + xs[:] = 1 + assert_equal(xh._data, [0,1,1,3,4]) + assert_equal(xs._data, [1,1,1,1,1]) + assert_equal(xh.mask, [1,0,0,1,1]) + assert_equal(xs.mask, nomask) + # Switch to soft mask + xh.soften_mask() + xh[:] = arange(5) + assert_equal(xh._data, [0,1,2,3,4]) + assert_equal(xh.mask, nomask) + # Switch back to hard mask + xh.harden_mask() + xh[xh<3] = masked + assert_equal(xh._data, [0,1,2,3,4]) + assert_equal(xh._mask, [1,1,1,0,0]) + xh[filled(xh>1,False)] = 5 + assert_equal(xh._data, [0,1,2,5,5]) + assert_equal(xh._mask, [1,1,1,0,0]) + # + xh = array([[1,2],[3,4]], mask = [[1,0],[0,0]], hard_mask=True) + xh[0] = 0 + assert_equal(xh._data, [[1,0],[3,4]]) + assert_equal(xh._mask, [[1,0],[0,0]]) + xh[-1,-1] = 5 + assert_equal(xh._data, [[1,0],[3,5]]) + assert_equal(xh._mask, [[1,0],[0,0]]) + xh[filled(xh<5,False)] = 2 + assert_equal(xh._data, [[1,2],[2,5]]) + assert_equal(xh._mask, [[1,0],[0,0]]) + # + "Another test of hardmask" + d = arange(5) + n = [0,0,0,1,1] + m = make_mask(n) + xh = array(d, mask = m, hard_mask=True) + xh[4:5] = 999 + #assert_equal(xh.mask.ctypes.data, m.ctypes.data) + xh[0:1] = 999 + assert_equal(xh._data,[999,1,2,3,4]) + + def test_smallmask(self): + "Checks the behaviour of _smallmask" + a = arange(10) + a[1] = masked + a[1] = 1 + assert_equal(a._mask, nomask) + a = arange(10) + a._smallmask = False + a[1] = masked + a[1] = 1 + assert_equal(a._mask, zeros(10)) + + +#------------------------------------------------------------------------------ + +class TestFillingValues(NumpyTestCase): # - def test_check_fill_value(self): + def test_check_on_scalar(self): "Test _check_fill_value" - _check_fill_value = numpy.ma.core._check_fill_value + _check_fill_value = np.ma.core._check_fill_value # fval = _check_fill_value(0,int) assert_equal(fval, 0) @@ -900,33 +834,34 @@ class TestMA(NumpyTestCase): # fval = _check_fill_value(1e+20,int) assert_equal(fval, default_fill_value(0)) - - def test_check_fill_value_with_fields(self): + + + def test_check_on_fields(self): "Tests _check_fill_value with records" - _check_fill_value = numpy.ma.core._check_fill_value - # + _check_fill_value = np.ma.core._check_fill_value ndtype = [('a',int),('b',float),('c',"|S3")] + # A check on a list should return a single record fval = _check_fill_value([-999,-999.9,"???"], ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), [-999,-999.9,"???"]) - # + # A check on Non should output the defaults fval = _check_fill_value(None, ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), [default_fill_value(0), default_fill_value(0.), default_fill_value("0")]) - # + #.....Using a flexi-ndarray as fill_value should work fill_val = np.array((-999,-999.9,"???"),dtype=ndtype) fval = _check_fill_value(fill_val, ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), [-999,-999.9,"???"]) - # + #.....Using a flexi-ndarray w/ a different type shouldn't matter fill_val = np.array((-999,-999.9,"???"), dtype=[("A",int),("B",float),("C","|S3")]) fval = _check_fill_value(fill_val, ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), [-999,-999.9,"???"]) - # + #.....Using an object-array shouldn't matter either fill_value = np.array((-999,-999.9,"???"), dtype=object) fval = _check_fill_value(fill_val, ndtype) assert(isinstance(fval,ndarray)) @@ -936,12 +871,13 @@ class TestMA(NumpyTestCase): fval = _check_fill_value(fill_val, ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), [-999,-999.9,"???"]) - # + #.....One-field-only flexi-ndarray should work as well ndtype = [("a",int)] fval = _check_fill_value(-999, ndtype) assert(isinstance(fval,ndarray)) assert_equal(fval.item(), (-999,)) - # + + def test_fillvalue_conversion(self): "Tests the behavior of fill_value during conversion" # We had a tailored comment to make sure special attributes are properly @@ -967,7 +903,30 @@ class TestMA(NumpyTestCase): assert_equal(b['a'].fill_value, a.fill_value) -#............................................................................... + def test_fillvalue(self): + "Yet more fun with the fill_value" + data = masked_array([1,2,3],fill_value=-999) + series = data[[0,2,1]] + assert_equal(series._fill_value, data._fill_value) + # + mtype = [('f',float_),('s','|S3')] + x = array([(1,'a'),(2,'b'),(np.pi,'pi')], dtype=mtype) + x.fill_value=999 + assert_equal(x.fill_value.item(),[999.,'999']) + assert_equal(x['f'].fill_value, 999) + assert_equal(x['s'].fill_value, '999') + # + x.fill_value=(9,'???') + assert_equal(x.fill_value.item(), (9,'???')) + assert_equal(x['f'].fill_value, 9) + assert_equal(x['s'].fill_value, '???') + # + x = array([1,2,3.1]) + x.fill_value = 999 + assert_equal(np.asarray(x.fill_value).dtype, float_) + assert_equal(x.fill_value, 999.) + +#------------------------------------------------------------------------------ class TestUfuncs(NumpyTestCase): "Test class for the application of ufuncs on MaskedArrays." @@ -997,7 +956,6 @@ class TestUfuncs(NumpyTestCase): 'less', 'greater', 'logical_and', 'logical_or', 'logical_xor', ]: - #print f try: uf = getattr(umath, f) except AttributeError: @@ -1028,31 +986,147 @@ class TestUfuncs(NumpyTestCase): assert_equal(amask.min(0), [5,6,7,8]) assert(amask.max(1)[0].mask) assert(amask.min(1)[0].mask) - #........................ - def test_minmax_funcs_with_out(self): - mask = numpy.random.rand(12).round() - xm = array(numpy.random.uniform(0,10,12),mask=mask) - xm.shape = (3,4) - for funcname in ('min', 'max'): - # Initialize - npfunc = getattr(numpy, funcname) - mafunc = getattr(coremodule, funcname) - # Use the np version - nout = np.empty((4,), dtype=int) - result = npfunc(xm,axis=0,out=nout) - assert(result is nout) - # Use the ma version - nout.fill(-999) - result = mafunc(xm,axis=0,out=nout) - assert(result is nout) -#............................................................................... -class TestArrayMathMethods(NumpyTestCase): +#------------------------------------------------------------------------------ + +class TestMaskedArrayInPlaceArithmetics(NumpyTestCase): + "Test MaskedArray Arithmetics" + + def setUp(self): + x = arange(10) + y = arange(10) + xm = arange(10) + xm[2] = masked + self.intdata = (x, y, xm) + self.floatdata = (x.astype(float), y.astype(float), xm.astype(float)) + + def test_inplace_addition_scalar(self): + """Test of inplace additions""" + (x, y, xm) = self.intdata + xm[2] = masked + x += 1 + assert_equal(x, y+1) + xm += 1 + assert_equal(xm, y+1) + # + warnings.simplefilter('ignore', DeprecationWarning) + (x, _, xm) = self.floatdata + id1 = x.raw_data().ctypes.data + x += 1. + assert (id1 == x.raw_data().ctypes.data) + assert_equal(x, y+1.) + warnings.simplefilter('default', DeprecationWarning) + + def test_inplace_addition_array(self): + """Test of inplace additions""" + (x, y, xm) = self.intdata + m = xm.mask + a = arange(10, dtype=float) + a[-1] = masked + x += a + xm += a + assert_equal(x,y+a) + assert_equal(xm,y+a) + assert_equal(xm.mask, mask_or(m,a.mask)) + + def test_inplace_subtraction_scalar(self): + """Test of inplace subtractions""" + (x, y, xm) = self.intdata + x -= 1 + assert_equal(x, y-1) + xm -= 1 + assert_equal(xm, y-1) + + def test_inplace_subtraction_array(self): + """Test of inplace subtractions""" + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float_) + a[-1] = masked + x -= a + xm -= a + assert_equal(x,y-a) + assert_equal(xm,y-a) + assert_equal(xm.mask, mask_or(m,a.mask)) + + def test_inplace_multiplication_scalar(self): + """Test of inplace multiplication""" + (x, y, xm) = self.floatdata + x *= 2.0 + assert_equal(x, y*2) + xm *= 2.0 + assert_equal(xm, y*2) + + def test_inplace_multiplication_array(self): + """Test of inplace multiplication""" + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float_) + a[-1] = masked + x *= a + xm *= a + assert_equal(x,y*a) + assert_equal(xm,y*a) + assert_equal(xm.mask, mask_or(m,a.mask)) + + def test_inplace_division_scalar_int(self): + """Test of inplace division""" + (x, y, xm) = self.intdata + x = arange(10)*2 + xm = arange(10)*2 + xm[2] = masked + x /= 2 + assert_equal(x, y) + xm /= 2 + assert_equal(xm, y) + + def test_inplace_division_scalar_float(self): + """Test of inplace division""" + (x, y, xm) = self.floatdata + x /= 2.0 + assert_equal(x, y/2.0) + xm /= arange(10) + assert_equal(xm, ones((10,))) + + def test_inplace_division_array_float(self): + """Test of inplace division""" + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float_) + a[-1] = masked + x /= a + xm /= a + assert_equal(x,y/a) + assert_equal(xm,y/a) + assert_equal(xm.mask, mask_or(mask_or(m,a.mask), (a==0))) + + def test_inplace_division_misc(self): + # + x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + # + z = xm/ym + assert_equal(z._mask, [1,1,1,0,0,1,1,0,0,0,1,1]) + assert_equal(z._data, [0.2,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.]) + # + xm = xm.copy() + xm /= ym + assert_equal(xm._mask, [1,1,1,0,0,1,1,0,0,0,1,1]) + assert_equal(xm._data, [1/5.,1.,1./3.,-1.,-pi/2.,-1.,5.,1.,1.,1.,2.,1.]) + + +#------------------------------------------------------------------------------ + +class TestMaskedArrayMethods(NumpyTestCase): "Test class for miscellaneous MaskedArrays methods." def setUp(self): "Base data definition." - x = numpy.array([ 8.375, 7.545, 8.828, 8.5 , 1.757, 5.928, + x = np.array([ 8.375, 7.545, 8.828, 8.5 , 1.757, 5.928, 8.43 , 7.78 , 9.865, 5.878, 8.979, 4.732, 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, 6.04 , 9.63 , 7.712, 3.382, 4.489, 6.479, @@ -1061,7 +1135,7 @@ class TestArrayMathMethods(NumpyTestCase): X = x.reshape(6,6) XX = x.reshape(3,2,2,3) - m = numpy.array([0, 1, 0, 1, 0, 0, + m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, @@ -1071,7 +1145,7 @@ class TestArrayMathMethods(NumpyTestCase): mX = array(data=X,mask=m.reshape(X.shape)) mXX = array(data=XX,mask=m.reshape(XX.shape)) - m2 = numpy.array([1, 1, 0, 1, 0, 0, + m2 = np.array([1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, @@ -1082,78 +1156,103 @@ class TestArrayMathMethods(NumpyTestCase): m2XX = array(data=XX,mask=m2.reshape(XX.shape)) self.d = (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) - #------------------------------------------------------ - def test_trace(self): - "Tests trace on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - mXdiag = mX.diagonal() - assert_equal(mX.trace(), mX.diagonal().compressed().sum()) - assert_almost_equal(mX.trace(), - X.trace() - sum(mXdiag.mask*X.diagonal(),axis=0)) + def test_generic_methods(self): + "Tests some MaskedArray methods." + a = array([1,3,2]) + b = array([1,3,2], mask=[1,0,1]) + assert_equal(a.any(), a.data.any()) + assert_equal(a.all(), a.data.all()) + assert_equal(a.argmax(), a.data.argmax()) + assert_equal(a.argmin(), a.data.argmin()) + assert_equal(a.choose(0,1,2,3,4), a.data.choose(0,1,2,3,4)) + assert_equal(a.compress([1,0,1]), a.data.compress([1,0,1])) + assert_equal(a.conj(), a.data.conj()) + assert_equal(a.conjugate(), a.data.conjugate()) + # + m = array([[1,2],[3,4]]) + assert_equal(m.diagonal(), m.data.diagonal()) + assert_equal(a.sum(), a.data.sum()) + assert_equal(a.take([1,2]), a.data.take([1,2])) + assert_equal(m.transpose(), m.data.transpose()) - def test_clip(self): - "Tests clip on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - clipped = mx.clip(2,8) - assert_equal(clipped.mask,mx.mask) - assert_equal(clipped.data,x.clip(2,8)) - assert_equal(clipped.data,mx.data.clip(2,8)) - def test_ptp(self): - "Tests ptp on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - (n,m) = X.shape - assert_equal(mx.ptp(),mx.compressed().ptp()) - rows = numpy.zeros(n,numpy.float_) - cols = numpy.zeros(m,numpy.float_) - for k in range(m): - cols[k] = mX[:,k].compressed().ptp() - for k in range(n): - rows[k] = mX[k].compressed().ptp() - assert_equal(mX.ptp(0),cols) - assert_equal(mX.ptp(1),rows) + def test_allany(self): + """Checks the any/all methods/functions.""" + x = np.array([[ 0.13, 0.26, 0.90], + [ 0.28, 0.33, 0.63], + [ 0.31, 0.87, 0.70]]) + m = np.array([[ True, False, False], + [False, False, False], + [True, True, False]], dtype=np.bool_) + mx = masked_array(x, mask=m) + xbig = np.array([[False, False, True], + [False, False, True], + [False, True, True]], dtype=np.bool_) + mxbig = (mx > 0.5) + mxsmall = (mx < 0.5) + # + assert (mxbig.all()==False) + assert (mxbig.any()==True) + assert_equal(mxbig.all(0),[False, False, True]) + assert_equal(mxbig.all(1), [False, False, True]) + assert_equal(mxbig.any(0),[False, False, True]) + assert_equal(mxbig.any(1), [True, True, True]) + # + assert (mxsmall.all()==False) + assert (mxsmall.any()==True) + assert_equal(mxsmall.all(0), [True, True, False]) + assert_equal(mxsmall.all(1), [False, False, False]) + assert_equal(mxsmall.any(0), [True, True, False]) + assert_equal(mxsmall.any(1), [True, True, False]) - def test_swapaxes(self): - "Tests swapaxes on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - mXswapped = mX.swapaxes(0,1) - assert_equal(mXswapped[-1],mX[:,-1]) - mXXswapped = mXX.swapaxes(0,2) - assert_equal(mXXswapped.shape,(2,2,3,3)) - def test_cumsumprod(self): - "Tests cumsum & cumprod on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - mXcp = mX.cumsum(0) - assert_equal(mXcp.data,mX.filled(0).cumsum(0)) - mXcp = mX.cumsum(1) - assert_equal(mXcp.data,mX.filled(0).cumsum(1)) + def test_allany_onmatrices(self): + x = np.array([[ 0.13, 0.26, 0.90], + [ 0.28, 0.33, 0.63], + [ 0.31, 0.87, 0.70]]) + X = np.matrix(x) + m = np.array([[ True, False, False], + [False, False, False], + [True, True, False]], dtype=np.bool_) + mX = masked_array(X, mask=m) + mXbig = (mX > 0.5) + mXsmall = (mX < 0.5) # - mXcp = mX.cumprod(0) - assert_equal(mXcp.data,mX.filled(1).cumprod(0)) - mXcp = mX.cumprod(1) - assert_equal(mXcp.data,mX.filled(1).cumprod(1)) + assert (mXbig.all()==False) + assert (mXbig.any()==True) + assert_equal(mXbig.all(0), np.matrix([False, False, True])) + assert_equal(mXbig.all(1), np.matrix([False, False, True]).T) + assert_equal(mXbig.any(0), np.matrix([False, False, True])) + assert_equal(mXbig.any(1), np.matrix([ True, True, True]).T) + # + assert (mXsmall.all()==False) + assert (mXsmall.any()==True) + assert_equal(mXsmall.all(0), np.matrix([True, True, False])) + assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T) + assert_equal(mXsmall.any(0), np.matrix([True, True, False])) + assert_equal(mXsmall.any(1), np.matrix([True, True, False]).T) - def test_varstd(self): - "Tests var & std on MaskedArrays." - (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d - assert_almost_equal(mX.var(axis=None),mX.compressed().var()) - assert_almost_equal(mX.std(axis=None),mX.compressed().std()) - assert_almost_equal(mX.std(axis=None,ddof=1), - mX.compressed().std(ddof=1)) - assert_almost_equal(mX.var(axis=None,ddof=1), - mX.compressed().var(ddof=1)) - assert_equal(mXX.var(axis=3).shape,XX.var(axis=3).shape) - assert_equal(mX.var().shape,X.var().shape) - (mXvar0,mXvar1) = (mX.var(axis=0), mX.var(axis=1)) - assert_almost_equal(mX.var(axis=None,ddof=2),mX.compressed().var(ddof=2)) - assert_almost_equal(mX.std(axis=None,ddof=2),mX.compressed().std(ddof=2)) - for k in range(6): - assert_almost_equal(mXvar1[k],mX[k].compressed().var()) - assert_almost_equal(mXvar0[k],mX[:,k].compressed().var()) - assert_almost_equal(numpy.sqrt(mXvar0[k]), mX[:,k].compressed().std()) - def test_argmin(self): + def test_allany_oddities(self): + "Some fun with all and any" + store = empty(1, dtype=bool) + full = array([1,2,3], mask=True) + # + assert(full.all() is masked) + full.all(out=store) + assert(store) + assert(store._mask, True) + assert(store is not masked) + # + store = empty(1, dtype=bool) + assert(full.any() is masked) + full.any(out=store) + assert(not store) + assert(store._mask, True) + assert(store is not masked) + + + def test_argmax_argmin(self): "Tests argmin & argmax on MaskedArrays." (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d # @@ -1176,6 +1275,90 @@ class TestArrayMathMethods(NumpyTestCase): assert_equal(mX.argmax(1), [2,4,1,1,4,1]) assert_equal(m2X.argmax(1), [2,4,1,1,1,1]) + + def test_clip(self): + "Tests clip on MaskedArrays." + x = np.array([ 8.375, 7.545, 8.828, 8.5 , 1.757, 5.928, + 8.43 , 7.78 , 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04 , 9.63 , 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0]) + mx = array(x,mask=m) + clipped = mx.clip(2,8) + assert_equal(clipped.mask,mx.mask) + assert_equal(clipped.data,x.clip(2,8)) + assert_equal(clipped.data,mx.data.clip(2,8)) + + + def test_compress(self): + "test compress" + a = masked_array([1., 2., 3., 4., 5.], fill_value=9999) + condition = (a > 1.5) & (a < 3.5) + assert_equal(a.compress(condition),[2.,3.]) + # + a[[2,3]] = masked + b = a.compress(condition) + assert_equal(b._data,[2.,3.]) + assert_equal(b._mask,[0,1]) + assert_equal(b.fill_value,9999) + assert_equal(b,a[condition]) + # + condition = (a<4.) + b = a.compress(condition) + assert_equal(b._data,[1.,2.,3.]) + assert_equal(b._mask,[0,0,1]) + assert_equal(b.fill_value,9999) + assert_equal(b,a[condition]) + # + a = masked_array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0]]) + b = a.compress(a.ravel() >= 22) + assert_equal(b._data, [30, 40, 50, 60]) + assert_equal(b._mask, [1,1,0,0]) + # + x = np.array([3,1,2]) + b = a.compress(x >= 2, axis=1) + assert_equal(b._data, [[10,30],[40,60]]) + assert_equal(b._mask, [[0,1],[1,0]]) + + + def test_compressed(self): + "Tests compressed" + a = array([1,2,3,4],mask=[0,0,0,0]) + b = a.compressed() + assert_equal(b, a) + a[0] = masked + b = a.compressed() + assert_equal(b, [2,3,4]) + # + a = array(np.matrix([1,2,3,4]), mask=[0,0,0,0]) + b = a.compressed() + assert_equal(b,a) + assert(isinstance(b,np.matrix)) + a[0,0] = masked + b = a.compressed() + assert_equal(b, [[2,3,4]]) + + + def test_empty(self): + "Tests empty/like" + datatype = [('a',int_),('b',float_),('c','|S8')] + a = masked_array([(1,1.1,'1.1'),(2,2.2,'2.2'),(3,3.3,'3.3')], + dtype=datatype) + assert_equal(len(a.fill_value.item()), len(datatype)) + # + b = empty_like(a) + assert_equal(b.shape, a.shape) + assert_equal(b.fill_value, a.fill_value) + # + b = empty(len(a), dtype=datatype) + assert_equal(b.shape, a.shape) + assert_equal(b.fill_value, a.fill_value) + + def test_put(self): "Tests put." d = arange(5) @@ -1207,6 +1390,7 @@ class TestArrayMathMethods(NumpyTestCase): assert_array_equal(x, [0,1,2,3,4,5,6,7,8,9,]) assert_equal(x.mask, [1,0,0,0,1,1,0,0,0,0]) + def test_put_hardmask(self): "Tests put on hardmask" d = arange(5) @@ -1216,184 +1400,76 @@ class TestArrayMathMethods(NumpyTestCase): xh.put([4,2,0,1,3],[1,2,3,4,5]) assert_equal(xh._data, [3,4,2,4,5]) - def test_take(self): - "Tests take" - x = masked_array([10,20,30,40],[0,1,0,1]) - assert_equal(x.take([0,0,3]), masked_array([10, 10, 40], [0,0,1]) ) - assert_equal(x.take([0,0,3]), x[[0,0,3]]) - assert_equal(x.take([[0,1],[0,1]]), - masked_array([[10,20],[10,20]], [[0,1],[0,1]]) ) - # - x = array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0,]]) - assert_equal(x.take([0,2], axis=1), - array([[10,30],[40,60]], mask=[[0,1],[1,0]])) - assert_equal(take(x, [0,2], axis=1), - array([[10,30],[40,60]], mask=[[0,1],[1,0]])) - #........................ - def test_anyall(self): - """Checks the any/all methods/functions.""" - x = numpy.array([[ 0.13, 0.26, 0.90], - [ 0.28, 0.33, 0.63], - [ 0.31, 0.87, 0.70]]) - m = numpy.array([[ True, False, False], - [False, False, False], - [True, True, False]], dtype=numpy.bool_) - mx = masked_array(x, mask=m) - xbig = numpy.array([[False, False, True], - [False, False, True], - [False, True, True]], dtype=numpy.bool_) - mxbig = (mx > 0.5) - mxsmall = (mx < 0.5) - # - assert (mxbig.all()==False) - assert (mxbig.any()==True) - assert_equal(mxbig.all(0),[False, False, True]) - assert_equal(mxbig.all(1), [False, False, True]) - assert_equal(mxbig.any(0),[False, False, True]) - assert_equal(mxbig.any(1), [True, True, True]) - # - assert (mxsmall.all()==False) - assert (mxsmall.any()==True) - assert_equal(mxsmall.all(0), [True, True, False]) - assert_equal(mxsmall.all(1), [False, False, False]) - assert_equal(mxsmall.any(0), [True, True, False]) - assert_equal(mxsmall.any(1), [True, True, False]) - # - X = numpy.matrix(x) - mX = masked_array(X, mask=m) - mXbig = (mX > 0.5) - mXsmall = (mX < 0.5) - # - assert (mXbig.all()==False) - assert (mXbig.any()==True) - assert_equal(mXbig.all(0), numpy.matrix([False, False, True])) - assert_equal(mXbig.all(1), numpy.matrix([False, False, True]).T) - assert_equal(mXbig.any(0), numpy.matrix([False, False, True])) - assert_equal(mXbig.any(1), numpy.matrix([ True, True, True]).T) - # - assert (mXsmall.all()==False) - assert (mXsmall.any()==True) - assert_equal(mXsmall.all(0), numpy.matrix([True, True, False])) - assert_equal(mXsmall.all(1), numpy.matrix([False, False, False]).T) - assert_equal(mXsmall.any(0), numpy.matrix([True, True, False])) - assert_equal(mXsmall.any(1), numpy.matrix([True, True, False]).T) - - def test_allany_oddities(self): - "Some fun with all and any" - store = empty(1, dtype=bool) - full = array([1,2,3], mask=True) - # - assert(full.all() is masked) - full.all(out=store) - assert(store) - assert(store._mask, True) - assert(store is not masked) - # - store = empty(1, dtype=bool) - assert(full.any() is masked) - full.any(out=store) - assert(not store) - assert(store._mask, True) - assert(store is not masked) + def test_putmask(self): + x = arange(6)+1 + mx = array(x, mask=[0,0,0,1,1,1]) + mask = [0,0,1,0,0,1] + # w/o mask, w/o masked values + xx = x.copy() + putmask(xx, mask, 99) + assert_equal(xx, [1,2,99,4,5,99]) + # w/ mask, w/o masked values + mxx = mx.copy() + putmask(mxx, mask, 99) + assert_equal(mxx._data, [1,2,99,4,5,99]) + assert_equal(mxx._mask, [0,0,0,1,1,0]) + # w/o mask, w/ masked values + values = array([10,20,30,40,50,60],mask=[1,1,1,0,0,0]) + xx = x.copy() + putmask(xx, mask, values) + assert_equal(xx._data, [1,2,30,4,5,60]) + assert_equal(xx._mask, [0,0,1,0,0,0]) + # w/ mask, w/ masked values + mxx = mx.copy() + putmask(mxx, mask, values) + assert_equal(mxx._data, [1,2,30,4,5,60]) + assert_equal(mxx._mask, [0,0,1,1,1,0]) + # w/ mask, w/ masked values + hardmask + mxx = mx.copy() + mxx.harden_mask() + putmask(mxx, mask, values) + assert_equal(mxx, [1,2,30,4,5,60]) - def test_keepmask(self): - "Tests the keep mask flag" - x = masked_array([1,2,3], mask=[1,0,0]) - mx = masked_array(x) - assert_equal(mx.mask, x.mask) - mx = masked_array(x, mask=[0,1,0], keep_mask=False) - assert_equal(mx.mask, [0,1,0]) - mx = masked_array(x, mask=[0,1,0], keep_mask=True) - assert_equal(mx.mask, [1,1,0]) - # We default to true - mx = masked_array(x, mask=[0,1,0]) - assert_equal(mx.mask, [1,1,0]) + def test_ravel(self): + "Tests ravel" + a = array([[1,2,3,4,5]], mask=[[0,1,0,0,0]]) + aravel = a.ravel() + assert_equal(a._mask.shape, a.shape) + a = array([0,0], mask=[1,1]) + aravel = a.ravel() + assert_equal(a._mask.shape, a.shape) + a = array(np.matrix([1,2,3,4,5]), mask=[[0,1,0,0,0]]) + aravel = a.ravel() + assert_equal(a.shape,(1,5)) + assert_equal(a._mask.shape, a.shape) + # Checs that small_mask is preserved + a = array([1,2,3,4],mask=[0,0,0,0],shrink=False) + assert_equal(a.ravel()._mask, [0,0,0,0]) + # Test that the fill_value is preserved + a.fill_value = -99 + a.shape = (2,2) + ar = a.ravel() + assert_equal(ar._mask, [0,0,0,0]) + assert_equal(ar._data, [1,2,3,4]) + assert_equal(ar.fill_value, -99) - def test_hardmask(self): - "Test hard_mask" - d = arange(5) - n = [0,0,0,1,1] - m = make_mask(n) - xh = array(d, mask = m, hard_mask=True) - # We need to copy, to avoid updating d in xh! - xs = array(d, mask = m, hard_mask=False, copy=True) - xh[[1,4]] = [10,40] - xs[[1,4]] = [10,40] - assert_equal(xh._data, [0,10,2,3,4]) - assert_equal(xs._data, [0,10,2,3,40]) - #assert_equal(xh.mask.ctypes.data, m.ctypes.data) - assert_equal(xs.mask, [0,0,0,1,0]) - assert(xh._hardmask) - assert(not xs._hardmask) - xh[1:4] = [10,20,30] - xs[1:4] = [10,20,30] - assert_equal(xh._data, [0,10,20,3,4]) - assert_equal(xs._data, [0,10,20,30,40]) - #assert_equal(xh.mask.ctypes.data, m.ctypes.data) - assert_equal(xs.mask, nomask) - xh[0] = masked - xs[0] = masked - assert_equal(xh.mask, [1,0,0,1,1]) - assert_equal(xs.mask, [1,0,0,0,0]) - xh[:] = 1 - xs[:] = 1 - assert_equal(xh._data, [0,1,1,3,4]) - assert_equal(xs._data, [1,1,1,1,1]) - assert_equal(xh.mask, [1,0,0,1,1]) - assert_equal(xs.mask, nomask) - # Switch to soft mask - xh.soften_mask() - xh[:] = arange(5) - assert_equal(xh._data, [0,1,2,3,4]) - assert_equal(xh.mask, nomask) - # Switch back to hard mask - xh.harden_mask() - xh[xh<3] = masked - assert_equal(xh._data, [0,1,2,3,4]) - assert_equal(xh._mask, [1,1,1,0,0]) - xh[filled(xh>1,False)] = 5 - assert_equal(xh._data, [0,1,2,5,5]) - assert_equal(xh._mask, [1,1,1,0,0]) - # - xh = array([[1,2],[3,4]], mask = [[1,0],[0,0]], hard_mask=True) - xh[0] = 0 - assert_equal(xh._data, [[1,0],[3,4]]) - assert_equal(xh._mask, [[1,0],[0,0]]) - xh[-1,-1] = 5 - assert_equal(xh._data, [[1,0],[3,5]]) - assert_equal(xh._mask, [[1,0],[0,0]]) - xh[filled(xh<5,False)] = 2 - assert_equal(xh._data, [[1,2],[2,5]]) - assert_equal(xh._mask, [[1,0],[0,0]]) - # - "Another test of hardmask" - d = arange(5) - n = [0,0,0,1,1] - m = make_mask(n) - xh = array(d, mask = m, hard_mask=True) - xh[4:5] = 999 - #assert_equal(xh.mask.ctypes.data, m.ctypes.data) - xh[0:1] = 999 - assert_equal(xh._data,[999,1,2,3,4]) - def test_smallmask(self): - "Checks the behaviour of _smallmask" - a = arange(10) - a[1] = masked - a[1] = 1 - assert_equal(a._mask, nomask) - a = arange(10) - a._smallmask = False - a[1] = masked - a[1] = 1 - assert_equal(a._mask, zeros(10)) + def test_reshape(self): + "Tests reshape" + x = arange(4) + x[0] = masked + y = x.reshape(2,2) + assert_equal(y.shape, (2,2,)) + assert_equal(y._mask.shape, (2,2,)) + assert_equal(x.shape, (4,)) + assert_equal(x._mask.shape, (4,)) def test_sort(self): "Test sort" - x = array([1,4,2,3],mask=[0,1,0,0],dtype=numpy.uint8) + x = array([1,4,2,3],mask=[0,1,0,0],dtype=np.uint8) # sortedx = sort(x) assert_equal(sortedx._data,[1,2,3,4]) @@ -1407,7 +1483,7 @@ class TestArrayMathMethods(NumpyTestCase): assert_equal(x._data,[1,2,3,4]) assert_equal(x._mask,[0,0,0,1]) # - x = array([1,4,2,3],mask=[0,1,0,0],dtype=numpy.uint8) + x = array([1,4,2,3],mask=[0,1,0,0],dtype=np.uint8) x.sort(endwith=False) assert_equal(x._data, [4,1,2,3]) assert_equal(x._mask, [1,0,0,0]) @@ -1416,14 +1492,15 @@ class TestArrayMathMethods(NumpyTestCase): sortedx = sort(x) assert(not isinstance(sorted, MaskedArray)) # - x = array([0,1,-1,-2,2], mask=nomask, dtype=numpy.int8) + x = array([0,1,-1,-2,2], mask=nomask, dtype=np.int8) sortedx = sort(x, endwith=False) assert_equal(sortedx._data, [-2,-1,0,1,2]) - x = array([0,1,-1,-2,2], mask=[0,1,0,0,1], dtype=numpy.int8) + x = array([0,1,-1,-2,2], mask=[0,1,0,0,1], dtype=np.int8) sortedx = sort(x, endwith=False) assert_equal(sortedx._data, [1,2,-2,-1,0]) assert_equal(sortedx._mask, [1,1,0,0,0]) + def test_sort_2d(self): "Check sort of 2D array." # 2D array w/o mask @@ -1465,60 +1542,59 @@ class TestArrayMathMethods(NumpyTestCase): assert_equal(am, an) - def test_ravel(self): - "Tests ravel" - a = array([[1,2,3,4,5]], mask=[[0,1,0,0,0]]) - aravel = a.ravel() - assert_equal(a._mask.shape, a.shape) - a = array([0,0], mask=[1,1]) - aravel = a.ravel() - assert_equal(a._mask.shape, a.shape) - a = array(numpy.matrix([1,2,3,4,5]), mask=[[0,1,0,0,0]]) - aravel = a.ravel() - assert_equal(a.shape,(1,5)) - assert_equal(a._mask.shape, a.shape) - # Checs that small_mask is preserved - a = array([1,2,3,4],mask=[0,0,0,0],shrink=False) - assert_equal(a.ravel()._mask, [0,0,0,0]) - # Test that the fill_value is preserved - a.fill_value = -99 - a.shape = (2,2) - ar = a.ravel() - assert_equal(ar._mask, [0,0,0,0]) - assert_equal(ar._data, [1,2,3,4]) - assert_equal(ar.fill_value, -99) + def test_squeeze(self): + "Check squeeze" + data = masked_array([[1,2,3]]) + assert_equal(data.squeeze(), [1,2,3]) + data = masked_array([[1,2,3]], mask=[[1,1,1]]) + assert_equal(data.squeeze(), [1,2,3]) + assert_equal(data.squeeze()._mask, [1,1,1]) + data = masked_array([[1]], mask=True) + assert(data.squeeze() is masked) - def test_reshape(self): - "Tests reshape" - x = arange(4) - x[0] = masked - y = x.reshape(2,2) - assert_equal(y.shape, (2,2,)) - assert_equal(y._mask.shape, (2,2,)) - assert_equal(x.shape, (4,)) - assert_equal(x._mask.shape, (4,)) - def test_compressed(self): - "Tests compressed" - a = array([1,2,3,4],mask=[0,0,0,0]) - b = a.compressed() - assert_equal(b, a) - a[0] = masked - b = a.compressed() - assert_equal(b, [2,3,4]) + def test_swapaxes(self): + "Tests swapaxes on MaskedArrays." + x = np.array([ 8.375, 7.545, 8.828, 8.5 , 1.757, 5.928, + 8.43 , 7.78 , 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04 , 9.63 , 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mX = array(x,mask=m).reshape(6,6) + mXX = mX.reshape(3,2,2,3) # - a = array(numpy.matrix([1,2,3,4]), mask=[0,0,0,0]) - b = a.compressed() - assert_equal(b,a) - assert(isinstance(b,numpy.matrix)) - a[0,0] = masked - b = a.compressed() - assert_equal(b, [[2,3,4]]) + mXswapped = mX.swapaxes(0,1) + assert_equal(mXswapped[-1],mX[:,-1]) + + mXXswapped = mXX.swapaxes(0,2) + assert_equal(mXXswapped.shape,(2,2,3,3)) + + + def test_take(self): + "Tests take" + x = masked_array([10,20,30,40],[0,1,0,1]) + assert_equal(x.take([0,0,3]), masked_array([10, 10, 40], [0,0,1]) ) + assert_equal(x.take([0,0,3]), x[[0,0,3]]) + assert_equal(x.take([[0,1],[0,1]]), + masked_array([[10,20],[10,20]], [[0,1],[0,1]]) ) + # + x = array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0,]]) + assert_equal(x.take([0,2], axis=1), + array([[10,30],[40,60]], mask=[[0,1],[1,0]])) + assert_equal(take(x, [0,2], axis=1), + array([[10,30],[40,60]], mask=[[0,1],[1,0]])) def test_tolist(self): "Tests to list" - x = array(numpy.arange(12)) + x = array(np.arange(12)) x[[1,-2]] = masked xlist = x.tolist() assert(xlist[1] is None) @@ -1539,90 +1615,122 @@ class TestArrayMathMethods(NumpyTestCase): assert_equal(x.tolist(), [(1,1.1,'one'),(2,2.2,'two'),(None,None,None)]) - def test_squeeze(self): - "Check squeeze" - data = masked_array([[1,2,3]]) - assert_equal(data.squeeze(), [1,2,3]) - data = masked_array([[1,2,3]], mask=[[1,1,1]]) - assert_equal(data.squeeze(), [1,2,3]) - assert_equal(data.squeeze()._mask, [1,1,1]) - data = masked_array([[1]], mask=True) - assert(data.squeeze() is masked) +#------------------------------------------------------------------------------ - def test_putmask(self): - x = arange(6)+1 - mx = array(x, mask=[0,0,0,1,1,1]) - mask = [0,0,1,0,0,1] - # w/o mask, w/o masked values - xx = x.copy() - putmask(xx, mask, 99) - assert_equal(xx, [1,2,99,4,5,99]) - # w/ mask, w/o masked values - mxx = mx.copy() - putmask(mxx, mask, 99) - assert_equal(mxx._data, [1,2,99,4,5,99]) - assert_equal(mxx._mask, [0,0,0,1,1,0]) - # w/o mask, w/ masked values - values = array([10,20,30,40,50,60],mask=[1,1,1,0,0,0]) - xx = x.copy() - putmask(xx, mask, values) - assert_equal(xx._data, [1,2,30,4,5,60]) - assert_equal(xx._mask, [0,0,1,0,0,0]) - # w/ mask, w/ masked values - mxx = mx.copy() - putmask(mxx, mask, values) - assert_equal(mxx._data, [1,2,30,4,5,60]) - assert_equal(mxx._mask, [0,0,1,1,1,0]) - # w/ mask, w/ masked values + hardmask - mxx = mx.copy() - mxx.harden_mask() - putmask(mxx, mask, values) - assert_equal(mxx, [1,2,30,4,5,60]) - def test_compress(self): - "test compress" - a = masked_array([1., 2., 3., 4., 5.], fill_value=9999) - condition = (a > 1.5) & (a < 3.5) - assert_equal(a.compress(condition),[2.,3.]) - # - a[[2,3]] = masked - b = a.compress(condition) - assert_equal(b._data,[2.,3.]) - assert_equal(b._mask,[0,1]) - assert_equal(b.fill_value,9999) - assert_equal(b,a[condition]) - # - condition = (a<4.) - b = a.compress(condition) - assert_equal(b._data,[1.,2.,3.]) - assert_equal(b._mask,[0,0,1]) - assert_equal(b.fill_value,9999) - assert_equal(b,a[condition]) - # - a = masked_array([[10,20,30],[40,50,60]], mask=[[0,0,1],[1,0,0]]) - b = a.compress(a.ravel() >= 22) - assert_equal(b._data, [30, 40, 50, 60]) - assert_equal(b._mask, [1,1,0,0]) - # - x = numpy.array([3,1,2]) - b = a.compress(x >= 2, axis=1) - assert_equal(b._data, [[10,30],[40,60]]) - assert_equal(b._mask, [[0,1],[1,0]]) - # - def test_empty(self): - "Tests empty/like" - datatype = [('a',int_),('b',float_),('c','|S8')] - a = masked_array([(1,1.1,'1.1'),(2,2.2,'2.2'),(3,3.3,'3.3')], - dtype=datatype) - assert_equal(len(a.fill_value.item()), len(datatype)) +class TestMaskArrayMathMethod(NumpyTestCase): + + def setUp(self): + "Base data definition." + x = np.array([ 8.375, 7.545, 8.828, 8.5 , 1.757, 5.928, + 8.43 , 7.78 , 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04 , 9.63 , 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + X = x.reshape(6,6) + XX = x.reshape(3,2,2,3) + + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mx = array(data=x,mask=m) + mX = array(data=X,mask=m.reshape(X.shape)) + mXX = array(data=XX,mask=m.reshape(XX.shape)) + + m2 = np.array([1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 1]) + m2x = array(data=x,mask=m2) + m2X = array(data=X,mask=m2.reshape(X.shape)) + m2XX = array(data=XX,mask=m2.reshape(XX.shape)) + self.d = (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) + + + def test_cumsumprod(self): + "Tests cumsum & cumprod on MaskedArrays." + (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d + mXcp = mX.cumsum(0) + assert_equal(mXcp.data,mX.filled(0).cumsum(0)) + mXcp = mX.cumsum(1) + assert_equal(mXcp.data,mX.filled(0).cumsum(1)) # - b = empty_like(a) - assert_equal(b.shape, a.shape) - assert_equal(b.fill_value, a.fill_value) + mXcp = mX.cumprod(0) + assert_equal(mXcp.data,mX.filled(1).cumprod(0)) + mXcp = mX.cumprod(1) + assert_equal(mXcp.data,mX.filled(1).cumprod(1)) + + + def test_cumsumprod_with_output(self): + "Tests cumsum/cumprod w/ output" + xm = array(np.random.uniform(0,10,12)).reshape(3,4) + xm[:,0] = xm[0] = xm[-1,-1] = masked # - b = empty(len(a), dtype=datatype) - assert_equal(b.shape, a.shape) - assert_equal(b.fill_value, a.fill_value) + for funcname in ('cumsum','cumprod'): + npfunc = getattr(np, funcname) + xmmeth = getattr(xm, funcname) + + # A ndarray as explicit input + output = np.empty((3,4), dtype=float) + output.fill(-9999) + result = npfunc(xm, axis=0,out=output) + # ... the result should be the given output + assert(result is output) + assert_equal(result, xmmeth(axis=0, out=output)) + # + output = empty((3,4), dtype=int) + result = xmmeth(axis=0, out=output) + assert(result is output) + + + def test_ptp(self): + "Tests ptp on MaskedArrays." + (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d + (n,m) = X.shape + assert_equal(mx.ptp(),mx.compressed().ptp()) + rows = np.zeros(n,np.float_) + cols = np.zeros(m,np.float_) + for k in range(m): + cols[k] = mX[:,k].compressed().ptp() + for k in range(n): + rows[k] = mX[k].compressed().ptp() + assert_equal(mX.ptp(0),cols) + assert_equal(mX.ptp(1),rows) + + + def test_trace(self): + "Tests trace on MaskedArrays." + (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d + mXdiag = mX.diagonal() + assert_equal(mX.trace(), mX.diagonal().compressed().sum()) + assert_almost_equal(mX.trace(), + X.trace() - sum(mXdiag.mask*X.diagonal(),axis=0)) + + + def test_varstd(self): + "Tests var & std on MaskedArrays." + (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d + assert_almost_equal(mX.var(axis=None),mX.compressed().var()) + assert_almost_equal(mX.std(axis=None),mX.compressed().std()) + assert_almost_equal(mX.std(axis=None,ddof=1), + mX.compressed().std(ddof=1)) + assert_almost_equal(mX.var(axis=None,ddof=1), + mX.compressed().var(ddof=1)) + assert_equal(mXX.var(axis=3).shape,XX.var(axis=3).shape) + assert_equal(mX.var().shape,X.var().shape) + (mXvar0,mXvar1) = (mX.var(axis=0), mX.var(axis=1)) + assert_almost_equal(mX.var(axis=None,ddof=2),mX.compressed().var(ddof=2)) + assert_almost_equal(mX.std(axis=None,ddof=2),mX.compressed().std(ddof=2)) + for k in range(6): + assert_almost_equal(mXvar1[k],mX[k].compressed().var()) + assert_almost_equal(mXvar0[k],mX[:,k].compressed().var()) + assert_almost_equal(np.sqrt(mXvar0[k]), mX[:,k].compressed().std()) def test_varstd_specialcases(self): @@ -1659,13 +1767,13 @@ class TestArrayMathMethods(NumpyTestCase): _ = method(out=nout, ddof=1) assert(np.isnan(nout)) +#------------------------------------------------------------------------------ - -class TestArrayMathMethodsComplex(NumpyTestCase): +class TestMaskedArrayMathMethodsComplex(NumpyTestCase): "Test class for miscellaneous MaskedArrays methods." def setUp(self): "Base data definition." - x = numpy.array([ 8.375j, 7.545j, 8.828j, 8.5j , 1.757j, 5.928, + x = np.array([ 8.375j, 7.545j, 8.828j, 8.5j , 1.757j, 5.928, 8.43 , 7.78 , 9.865, 5.878, 8.979, 4.732, 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, 6.04 , 9.63 , 7.712, 3.382, 4.489, 6.479j, @@ -1674,7 +1782,7 @@ class TestArrayMathMethodsComplex(NumpyTestCase): X = x.reshape(6,6) XX = x.reshape(3,2,2,3) - m = numpy.array([0, 1, 0, 1, 0, 0, + m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, @@ -1684,7 +1792,7 @@ class TestArrayMathMethodsComplex(NumpyTestCase): mX = array(data=X,mask=m.reshape(X.shape)) mXX = array(data=XX,mask=m.reshape(XX.shape)) - m2 = numpy.array([1, 1, 0, 1, 0, 0, + m2 = np.array([1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, @@ -1709,19 +1817,65 @@ class TestArrayMathMethodsComplex(NumpyTestCase): for k in range(6): assert_almost_equal(mXvar1[k],mX[k].compressed().var()) assert_almost_equal(mXvar0[k],mX[:,k].compressed().var()) - assert_almost_equal(numpy.sqrt(mXvar0[k]), mX[:,k].compressed().std()) + assert_almost_equal(np.sqrt(mXvar0[k]), mX[:,k].compressed().std()) -#.............................................................................. -class TestMiscFunctions(NumpyTestCase): +#------------------------------------------------------------------------------ + +class TestMaskedArrayFunctions(NumpyTestCase): "Test class for miscellaneous functions." # - def test_masked_where(self): + def setUp(self): + x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + a10 = 10. + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + z = np.array([-.5, 0., .5, .8]) + zm = masked_array(z, mask=[0,1,0,0]) + xf = np.where(m1, 1.e+20, x) + xm.set_fill_value(1.e+20) + self.info = (xm, ym) + + # + def test_masked_where_bool(self): x = [1,2] y = masked_where(False,x) assert_equal(y,[1,2]) assert_equal(y[1],2) - # + + def test_masked_where_condition(self): + "Tests masking functions." + x = array([1.,2.,3.,4.,5.]) + x[2] = masked + assert_equal(masked_where(greater(x, 2), x), masked_greater(x,2)) + assert_equal(masked_where(greater_equal(x, 2), x), masked_greater_equal(x,2)) + assert_equal(masked_where(less(x, 2), x), masked_less(x,2)) + assert_equal(masked_where(less_equal(x, 2), x), masked_less_equal(x,2)) + assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x,2)) + assert_equal(masked_where(equal(x, 2), x), masked_equal(x,2)) + assert_equal(masked_where(not_equal(x,2), x), masked_not_equal(x,2)) + assert_equal(masked_where([1,1,0,0,0], [1,2,3,4,5]), [99,99,3,4,5]) + + def test_masked_where_oddities(self): + """Tests some generic features.""" + atest = ones((10,10,10), dtype=float_) + btest = zeros(atest.shape, MaskType) + ctest = masked_where(btest,atest) + assert_equal(atest,ctest) + + + def test_masked_otherfunctions(self): + assert_equal(masked_inside(range(5), 1, 3), [0, 199, 199, 199, 4]) + assert_equal(masked_outside(range(5), 1, 3),[199,1,2,3,199]) + assert_equal(masked_inside(array(range(5), mask=[1,0,0,0,0]), 1, 3).mask, [1,1,1,1,0]) + assert_equal(masked_outside(array(range(5), mask=[0,1,0,0,0]), 1, 3).mask, [1,1,0,0,1]) + assert_equal(masked_equal(array(range(5), mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,0]) + assert_equal(masked_not_equal(array([2,2,1,2,1], mask=[1,0,0,0,0]), 2).mask, [1,0,1,0,1]) + + def test_round(self): a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890], mask=[0,1,0,0,0]) @@ -1731,12 +1885,45 @@ class TestMiscFunctions(NumpyTestCase): b = empty_like(a) a.round(out=b) assert_equal(b, [1., 2., 3., 5., 6.]) - # + + x = array([1.,2.,3.,4.,5.]) + c = array([1,1,1,0,0]) + x[2] = masked + z = where(c, x, -x) + assert_equal(z, [1.,2.,0., -4., -5]) + c[0] = masked + z = where(c, x, -x) + assert_equal(z, [1.,2.,0., -4., -5]) + assert z[0] is masked + assert z[1] is not masked + assert z[2] is masked + + + def test_round_with_output(self): + "Testing round with an explicit output" + + xm = array(np.random.uniform(0,10,12)).reshape(3,4) + xm[:,0] = xm[0] = xm[-1,-1] = masked + + # A ndarray as explicit input + output = np.empty((3,4), dtype=float) + output.fill(-9999) + result = np.round(xm, decimals=2,out=output) + # ... the result should be the given output + assert(result is output) + assert_equal(result, xm.round(decimals=2, out=output)) + # + output = empty((3,4), dtype=float) + result = xm.round(decimals=2, out=output) + assert(result is output) + + def test_identity(self): a = identity(5) assert(isinstance(a, MaskedArray)) - assert_equal(a, numpy.identity(5)) - # + assert_equal(a, np.identity(5)) + + def test_power(self): x = -1.1 assert_almost_equal(power(x,2.), 1.21) @@ -1759,6 +1946,89 @@ class TestMiscFunctions(NumpyTestCase): assert_almost_equal(x._data,y._data) + def test_where(self): + "Test the where function" + x = np.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + a10 = 10. + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + z = np.array([-.5, 0., .5, .8]) + zm = masked_array(z, mask=[0,1,0,0]) + xf = np.where(m1, 1.e+20, x) + xm.set_fill_value(1.e+20) + + d = where(xm>2,xm,-9) + assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.]) + assert_equal(d._mask, xm._mask) + d = where(xm>2,-9,ym) + assert_equal(d, [5.,0.,3., 2., -1.,-9.,-9., -10., -9., 1., 0., -9.]) + assert_equal(d._mask, [1,0,1,0,0,0,1,0,0,0,0,0]) + d = where(xm>2, xm, masked) + assert_equal(d, [-9.,-9.,-9.,-9., -9., 4., -9., -9., 10., -9., -9., 3.]) + tmp = xm._mask.copy() + tmp[(xm<=2).filled(True)] = True + assert_equal(d._mask, tmp) + # + ixm = xm.astype(int_) + d = where(ixm>2, ixm, masked) + assert_equal(d, [-9,-9,-9,-9, -9, 4, -9, -9, 10, -9, -9, 3]) + assert_equal(d.dtype, ixm.dtype) + + def test_where_with_masked_choice(self): + x = arange(10) + x[3] = masked + c = x >= 8 + # Set False to masked + z = where(c , x, masked) + assert z.dtype is x.dtype + assert z[3] is masked + assert z[4] is masked + assert z[7] is masked + assert z[8] is not masked + assert z[9] is not masked + assert_equal(x,z) + # Set True to masked + z = where(c , masked, x) + assert z.dtype is x.dtype + assert z[3] is masked + assert z[4] is not masked + assert z[7] is not masked + assert z[8] is masked + assert z[9] is masked + + def test_where_with_masked_condition(self): + x = array([1.,2.,3.,4.,5.]) + c = array([1,1,1,0,0]) + x[2] = masked + z = where(c, x, -x) + assert_equal(z, [1.,2.,0., -4., -5]) + c[0] = masked + z = where(c, x, -x) + assert_equal(z, [1.,2.,0., -4., -5]) + assert z[0] is masked + assert z[1] is not masked + assert z[2] is masked + # + x = arange(1,6) + x[-1] = masked + y = arange(1,6)*10 + y[2] = masked + c = array([1,1,1,0,0], mask=[1,0,0,0,0]) + cm = c.filled(1) + z = where(c,x,y) + zm = where(cm,x,y) + assert_equal(z, zm) + assert getmask(zm) is nomask + assert_equal(zm, [1,2,3,40,50]) + z = where(c, masked, 1) + assert_equal(z, [99,99,99,1,1]) + z = where(c, 1, masked) + assert_equal(z, [99, 1, 1, 99, 99]) + + def test_choose(self): "Test choose" choices = [[0, 1, 2, 3], [10, 11, 12, 13], @@ -1805,71 +2075,78 @@ class TestMiscFunctions(NumpyTestCase): chosen = choose(indices_, choices, mode='wrap', out=store) assert_equal(store, array([999999, 31, 12, 999999])) - def test_functions_with_output(self): - xm = array(np.random.uniform(0,10,12)).reshape(3,4) - xm[:,0] = xm[0] = xm[-1,-1] = masked - # - funclist = ('sum','prod','var','std', 'max', 'min', 'ptp', 'mean', ) - # - for funcname in funclist: - npfunc = getattr(np, funcname) - xmmeth = getattr(xm, funcname) - - # A ndarray as explicit input - output = np.empty(4, dtype=float) - output.fill(-9999) - result = npfunc(xm, axis=0,out=output) - # ... the result should be the given output - assert(result is output) - assert_equal(result, xmmeth(axis=0, out=output)) - # - output = empty(4, dtype=int) - result = xmmeth(axis=0, out=output) - assert(result is output) - assert(output[0] is masked) - - def test_cumsumprod_with_output(self): - "Tests cumsum/cumprod w/ output" - xm = array(np.random.uniform(0,10,12)).reshape(3,4) - xm[:,0] = xm[0] = xm[-1,-1] = masked - # - funclist = ('cumsum','cumprod') - # - for funcname in funclist: - npfunc = getattr(np, funcname) - xmmeth = getattr(xm, funcname) - - # A ndarray as explicit input - output = np.empty((3,4), dtype=float) - output.fill(-9999) - result = npfunc(xm, axis=0,out=output) - # ... the result should be the given output - assert(result is output) - assert_equal(result, xmmeth(axis=0, out=output)) - # - output = empty((3,4), dtype=int) - result = xmmeth(axis=0, out=output) - assert(result is output) +#------------------------------------------------------------------------------ +class TestMaskedFields(NumpyTestCase): + # + def setUp(self): + ilist = [1,2,3,4,5] + flist = [1.1,2.2,3.3,4.4,5.5] + slist = ['one','two','three','four','five'] + ddtype = [('a',int),('b',float),('c','|S8')] + mdtype = [('a',bool),('b',bool),('c',bool)] + mask = [0,1,0,0,1] + base = array(zip(ilist,flist,slist), mask=mask, dtype=ddtype) + self.data = dict(base=base, mask=mask, ddtype=ddtype, mdtype=mdtype) + + def test_set_records_masks(self): + base = self.data['base'] + mdtype = self.data['mdtype'] + # Set w/ nomask or masked + base.mask = nomask + assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype)) + base.mask = masked + assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype)) + # Set w/ simple boolean + base.mask = False + assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype)) + base.mask = True + assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype)) + # Set w/ list + base.mask = [0,0,0,1,1] + assert_equal_records(base._mask, + np.array([(x,x,x) for x in [0,0,0,1,1]], + dtype=mdtype)) + + def test_set_record_element(self): + "Check setting an element of a record)" + base = self.data['base'] + (base_a, base_b, base_c) = (base['a'], base['b'], base['c']) + base[0] = (np.pi, np.pi, 'pi') + + assert_equal(base_a.dtype, int) + assert_equal(base_a.data, [3,2,3,4,5]) + + assert_equal(base_b.dtype, float) + assert_equal(base_b.data, [np.pi, 2.2, 3.3, 4.4, 5.5]) + + assert_equal(base_c.dtype, '|S8') + assert_equal(base_c.data, ['pi','two','three','four','five']) - def test_round_with_output(self): - "Testing round with an explicit output" + def test_set_record_slice(self): + base = self.data['base'] + (base_a, base_b, base_c) = (base['a'], base['b'], base['c']) + base[:3] = (np.pi, np.pi, 'pi') - xm = array(np.random.uniform(0,10,12)).reshape(3,4) - xm[:,0] = xm[0] = xm[-1,-1] = masked + assert_equal(base_a.dtype, int) + assert_equal(base_a.data, [3,3,3,4,5]) - # A ndarray as explicit input - output = np.empty((3,4), dtype=float) - output.fill(-9999) - result = np.round(xm, decimals=2,out=output) - # ... the result should be the given output - assert(result is output) - assert_equal(result, xm.round(decimals=2, out=output)) + assert_equal(base_b.dtype, float) + assert_equal(base_b.data, [np.pi, np.pi, np.pi, 4.4, 5.5]) + + assert_equal(base_c.dtype, '|S8') + assert_equal(base_c.data, ['pi','pi','pi','four','five']) + + def test_mask_element(self): + "Check record access" + base = self.data['base'] + (base_a, base_b, base_c) = (base['a'], base['b'], base['c']) + base[0] = masked # - output = empty((3,4), dtype=float) - result = xm.round(decimals=2, out=output) - assert(result is output) + for n in ('a','b','c'): + assert_equal(base[n].mask, [1,1,0,0,1]) + assert_equal(base[n].data, base.data[n]) ############################################################################### #------------------------------------------------------------------------------ diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py index 6612e83a1..805800c53 100644 --- a/numpy/ma/tests/test_extras.py +++ b/numpy/ma/tests/test_extras.py @@ -11,7 +11,7 @@ __version__ = '1.0' __revision__ = "$Revision: 3473 $" __date__ = '$Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $' -import numpy as N +import numpy as np from numpy.testing import NumpyTest, NumpyTestCase from numpy.testing.utils import build_err_msg @@ -52,12 +52,15 @@ class TestAverage(NumpyTestCase): assert_equal(average(x, axis=0), 2.5) assert_equal(average(x, axis=0, weights=w1), 2.5) y = array([arange(6, dtype=float_), 2.0*arange(6)]) - assert_equal(average(y, None), N.add.reduce(N.arange(6))*3./12.) - assert_equal(average(y, axis=0), N.arange(6) * 3./2.) - assert_equal(average(y, axis=1), [average(x,axis=0), average(x,axis=0) * 2.0]) + assert_equal(average(y, None), np.add.reduce(np.arange(6))*3./12.) + assert_equal(average(y, axis=0), np.arange(6) * 3./2.) + assert_equal(average(y, axis=1), + [average(x,axis=0), average(x,axis=0) * 2.0]) assert_equal(average(y, None, weights=w2), 20./6.) - assert_equal(average(y, axis=0, weights=w2), [0.,1.,2.,3.,4.,10.]) - assert_equal(average(y, axis=1), [average(x,axis=0), average(x,axis=0) * 2.0]) + assert_equal(average(y, axis=0, weights=w2), + [0.,1.,2.,3.,4.,10.]) + assert_equal(average(y, axis=1), + [average(x,axis=0), average(x,axis=0) * 2.0]) m1 = zeros(6) m2 = [0,0,1,1,0,0] m3 = [[0,0,1,1,0,0],[0,1,1,1,1,0]] @@ -115,26 +118,26 @@ class TestConcatenator(NumpyTestCase): "Tests mr_ on 2D arrays." a_1 = rand(5,5) a_2 = rand(5,5) - m_1 = N.round_(rand(5,5),0) - m_2 = N.round_(rand(5,5),0) + m_1 = np.round_(rand(5,5),0) + m_2 = np.round_(rand(5,5),0) b_1 = masked_array(a_1,mask=m_1) b_2 = masked_array(a_2,mask=m_2) d = mr_['1',b_1,b_2] # append columns assert(d.shape == (5,10)) assert_array_equal(d[:,:5],b_1) assert_array_equal(d[:,5:],b_2) - assert_array_equal(d.mask, N.r_['1',m_1,m_2]) + assert_array_equal(d.mask, np.r_['1',m_1,m_2]) d = mr_[b_1,b_2] assert(d.shape == (10,5)) assert_array_equal(d[:5,:],b_1) assert_array_equal(d[5:,:],b_2) - assert_array_equal(d.mask, N.r_[m_1,m_2]) + assert_array_equal(d.mask, np.r_[m_1,m_2]) class TestNotMasked(NumpyTestCase): "Tests notmasked_edges and notmasked_contiguous." def check_edges(self): "Tests unmasked_edges" - a = masked_array(N.arange(24).reshape(3,8), + a = masked_array(np.arange(24).reshape(3,8), mask=[[0,0,0,0,1,1,1,0], [1,1,1,1,1,1,1,1], [0,0,0,0,0,0,1,0],]) @@ -151,7 +154,7 @@ class TestNotMasked(NumpyTestCase): def check_contiguous(self): "Tests notmasked_contiguous" - a = masked_array(N.arange(24).reshape(3,8), + a = masked_array(np.arange(24).reshape(3,8), mask=[[0,0,0,0,1,1,1,1], [1,1,1,1,1,1,1,1], [0,0,0,0,0,0,1,0],]) @@ -176,7 +179,7 @@ class Test2DFunctions(NumpyTestCase): "Tests 2D functions" def check_compress2d(self): "Tests compress2d" - x = array(N.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]]) + x = array(np.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]]) assert_equal(compress_rowcols(x), [[4,5],[7,8]] ) assert_equal(compress_rowcols(x,0), [[3,4,5],[6,7,8]] ) assert_equal(compress_rowcols(x,1), [[1,2],[4,5],[7,8]] ) @@ -195,7 +198,7 @@ class Test2DFunctions(NumpyTestCase): # def check_mask_rowcols(self): "Tests mask_rowcols." - x = array(N.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]]) + x = array(np.arange(9).reshape(3,3), mask=[[1,0,0],[0,0,0],[0,0,0]]) assert_equal(mask_rowcols(x).mask, [[1,1,1],[1,0,0],[1,0,0]] ) assert_equal(mask_rowcols(x,0).mask, [[1,1,1],[0,0,0],[0,0,0]] ) assert_equal(mask_rowcols(x,1).mask, [[1,0,0],[1,0,0],[1,0,0]] ) @@ -208,13 +211,16 @@ class Test2DFunctions(NumpyTestCase): assert_equal(mask_rowcols(x,0).mask, [[1,1,1],[1,1,1],[0,0,0]] ) assert_equal(mask_rowcols(x,1,).mask, [[1,1,0],[1,1,0],[1,1,0]] ) x = array(x._data, mask=[[1,0,0],[0,1,0],[0,0,1]]) - assert(mask_rowcols(x).all()) - assert(mask_rowcols(x,0).all()) - assert(mask_rowcols(x,1).all()) + assert(mask_rowcols(x).all() is masked) + assert(mask_rowcols(x,0).all() is masked) + assert(mask_rowcols(x,1).all() is masked) + assert(mask_rowcols(x).mask.all()) + assert(mask_rowcols(x,0).mask.all()) + assert(mask_rowcols(x,1).mask.all()) # def test_dot(self): "Tests dot product" - n = N.arange(1,7) + n = np.arange(1,7) # m = [1,0,0,0,0,0] a = masked_array(n, mask=m).reshape(2,3) @@ -224,9 +230,9 @@ class Test2DFunctions(NumpyTestCase): c = dot(b,a,True) assert_equal(c.mask, [[1,1,1],[1,0,0],[1,0,0]]) c = dot(a,b,False) - assert_equal(c, N.dot(a.filled(0), b.filled(0))) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) c = dot(b,a,False) - assert_equal(c, N.dot(b.filled(0), a.filled(0))) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) # m = [0,0,0,0,0,1] a = masked_array(n, mask=m).reshape(2,3) @@ -236,10 +242,10 @@ class Test2DFunctions(NumpyTestCase): c = dot(b,a,True) assert_equal(c.mask, [[0,0,1],[0,0,1],[1,1,1]]) c = dot(a,b,False) - assert_equal(c, N.dot(a.filled(0), b.filled(0))) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) assert_equal(c, dot(a,b)) c = dot(b,a,False) - assert_equal(c, N.dot(b.filled(0), a.filled(0))) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) # m = [0,0,0,0,0,0] a = masked_array(n, mask=m).reshape(2,3) @@ -254,37 +260,37 @@ class Test2DFunctions(NumpyTestCase): c = dot(a,b,True) assert_equal(c.mask,[[1,1],[0,0]]) c = dot(a,b,False) - assert_equal(c, N.dot(a.filled(0),b.filled(0))) + assert_equal(c, np.dot(a.filled(0),b.filled(0))) c = dot(b,a,True) assert_equal(c.mask,[[1,0,0],[1,0,0],[1,0,0]]) c = dot(b,a,False) - assert_equal(c, N.dot(b.filled(0),a.filled(0))) + assert_equal(c, np.dot(b.filled(0),a.filled(0))) # a = masked_array(n, mask=[0,0,0,0,0,1]).reshape(2,3) b = masked_array(n, mask=[0,0,0,0,0,0]).reshape(3,2) c = dot(a,b,True) assert_equal(c.mask,[[0,0],[1,1]]) c = dot(a,b) - assert_equal(c, N.dot(a.filled(0),b.filled(0))) + assert_equal(c, np.dot(a.filled(0),b.filled(0))) c = dot(b,a,True) assert_equal(c.mask,[[0,0,1],[0,0,1],[0,0,1]]) c = dot(b,a,False) - assert_equal(c, N.dot(b.filled(0), a.filled(0))) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) # a = masked_array(n, mask=[0,0,0,0,0,1]).reshape(2,3) b = masked_array(n, mask=[0,0,1,0,0,0]).reshape(3,2) c = dot(a,b,True) assert_equal(c.mask,[[1,0],[1,1]]) c = dot(a,b,False) - assert_equal(c, N.dot(a.filled(0),b.filled(0))) + assert_equal(c, np.dot(a.filled(0),b.filled(0))) c = dot(b,a,True) assert_equal(c.mask,[[0,0,1],[1,1,1],[0,0,1]]) c = dot(b,a,False) - assert_equal(c, N.dot(b.filled(0),a.filled(0))) + assert_equal(c, np.dot(b.filled(0),a.filled(0))) def test_ediff1d(self): "Tests mediff1d" - x = masked_array(N.arange(5), mask=[1,0,0,0,1]) + x = masked_array(np.arange(5), mask=[1,0,0,0,1]) difx_d = (x._data[1:]-x._data[:-1]) difx_m = (x._mask[1:]-x._mask[:-1]) dx = ediff1d(x) @@ -292,29 +298,29 @@ class Test2DFunctions(NumpyTestCase): assert_equal(dx._mask, difx_m) # dx = ediff1d(x, to_begin=masked) - assert_equal(dx._data, N.r_[0,difx_d]) - assert_equal(dx._mask, N.r_[1,difx_m]) + assert_equal(dx._data, np.r_[0,difx_d]) + assert_equal(dx._mask, np.r_[1,difx_m]) dx = ediff1d(x, to_begin=[1,2,3]) - assert_equal(dx._data, N.r_[[1,2,3],difx_d]) - assert_equal(dx._mask, N.r_[[0,0,0],difx_m]) + assert_equal(dx._data, np.r_[[1,2,3],difx_d]) + assert_equal(dx._mask, np.r_[[0,0,0],difx_m]) # dx = ediff1d(x, to_end=masked) - assert_equal(dx._data, N.r_[difx_d,0]) - assert_equal(dx._mask, N.r_[difx_m,1]) + assert_equal(dx._data, np.r_[difx_d,0]) + assert_equal(dx._mask, np.r_[difx_m,1]) dx = ediff1d(x, to_end=[1,2,3]) - assert_equal(dx._data, N.r_[difx_d,[1,2,3]]) - assert_equal(dx._mask, N.r_[difx_m,[0,0,0]]) + assert_equal(dx._data, np.r_[difx_d,[1,2,3]]) + assert_equal(dx._mask, np.r_[difx_m,[0,0,0]]) # dx = ediff1d(x, to_end=masked, to_begin=masked) - assert_equal(dx._data, N.r_[0,difx_d,0]) - assert_equal(dx._mask, N.r_[1,difx_m,1]) + assert_equal(dx._data, np.r_[0,difx_d,0]) + assert_equal(dx._mask, np.r_[1,difx_m,1]) dx = ediff1d(x, to_end=[1,2,3], to_begin=masked) - assert_equal(dx._data, N.r_[0,difx_d,[1,2,3]]) - assert_equal(dx._mask, N.r_[1,difx_m,[0,0,0]]) + assert_equal(dx._data, np.r_[0,difx_d,[1,2,3]]) + assert_equal(dx._mask, np.r_[1,difx_m,[0,0,0]]) # dx = ediff1d(x._data, to_end=masked, to_begin=masked) - assert_equal(dx._data, N.r_[0,difx_d,0]) - assert_equal(dx._mask, N.r_[1,0,0,0,0,1]) + assert_equal(dx._data, np.r_[0,difx_d,0]) + assert_equal(dx._mask, np.r_[1,0,0,0,0,1]) class TestApplyAlongAxis(NumpyTestCase): "Tests 2D functions" diff --git a/numpy/ma/tests/test_mrecords.py b/numpy/ma/tests/test_mrecords.py index 584f62517..f9a246410 100644 --- a/numpy/ma/tests/test_mrecords.py +++ b/numpy/ma/tests/test_mrecords.py @@ -46,7 +46,8 @@ class TestMRecords(NumpyTestCase): "Test creation by view" base = self.base mbase = base.view(mrecarray) - assert_equal(mbase._mask, base._mask) + assert_equal(mbase.recordmask, base.recordmask) + assert_equal_records(mbase._mask, base._mask) assert isinstance(mbase._data, recarray) assert_equal_records(mbase._data, base._data.view(recarray)) for field in ('a','b','c'): @@ -66,14 +67,18 @@ class TestMRecords(NumpyTestCase): assert isinstance(mbase_first, mrecarray) assert_equal(mbase_first.dtype, mbase.dtype) assert_equal(mbase_first.tolist(), (1,1.1,'one')) - assert_equal(mbase_first.mask, nomask) + # Used to be mask, now it's recordmask + assert_equal(mbase_first.recordmask, nomask) + # _fieldmask and _mask should be the same thing assert_equal(mbase_first._fieldmask.item(), (False, False, False)) + assert_equal(mbase_first._mask.item(), (False, False, False)) assert_equal(mbase_first['a'], mbase['a'][0]) mbase_last = mbase[-1] assert isinstance(mbase_last, mrecarray) assert_equal(mbase_last.dtype, mbase.dtype) assert_equal(mbase_last.tolist(), (None,None,None)) - assert_equal(mbase_last.mask, True) + # Used to be mask, now it's recordmask + assert_equal(mbase_last.recordmask, True) assert_equal(mbase_last._fieldmask.item(), (True, True, True)) assert_equal(mbase_last['a'], mbase['a'][-1]) assert (mbase_last['a'] is masked) @@ -81,7 +86,11 @@ class TestMRecords(NumpyTestCase): mbase_sl = mbase[:2] assert isinstance(mbase_sl, mrecarray) assert_equal(mbase_sl.dtype, mbase.dtype) - assert_equal(mbase_sl._mask, [0,1]) + # Used to be mask, now it's recordmask + assert_equal(mbase_sl.recordmask, [0,1]) + assert_equal_records(mbase_sl.mask, + np.array([(False,False,False),(True,True,True)], + dtype=mbase._mask.dtype)) assert_equal_records(mbase_sl, base[:2].view(mrecarray)) for field in ('a','b','c'): assert_equal(getattr(mbase_sl,field), base[:2][field]) @@ -100,13 +109,16 @@ class TestMRecords(NumpyTestCase): mbase.a = 1 assert_equal(mbase['a']._data, [1]*5) assert_equal(ma.getmaskarray(mbase['a']), [0]*5) - assert_equal(mbase._mask, [False]*5) + # Use to be _mask, now it's recordmask + assert_equal(mbase.recordmask, [False]*5) assert_equal(mbase._fieldmask.tolist(), np.array([(0,0,0),(0,1,1),(0,0,0),(0,0,0),(0,1,1)], dtype=bool)) # Set a field to mask ........................ mbase.c = masked + # Use to be mask, and now it's still mask ! assert_equal(mbase.c.mask, [1]*5) + assert_equal(mbase.c.recordmask, [1]*5) assert_equal(ma.getmaskarray(mbase['c']), [1]*5) assert_equal(ma.getdata(mbase['c']), ['N/A']*5) assert_equal(mbase._fieldmask.tolist(), @@ -201,10 +213,11 @@ class TestMRecords(NumpyTestCase): assert_equal(mbase._fieldmask.tolist(), np.array([(0,0,0),(1,1,1),(0,0,0),(1,1,1),(1,1,1)], dtype=bool)) - assert_equal(mbase._mask, [0,1,0,1,1]) + # Used to be mask, now it's recordmask! + assert_equal(mbase.recordmask, [0,1,0,1,1]) # Set slices ................................. mbase = base.view(mrecarray).copy() - mbase[:2] = 5 + mbase[:2] = (5,5,5) assert_equal(mbase.a._data, [5,5,3,4,5]) assert_equal(mbase.a._mask, [0,0,0,0,1]) assert_equal(mbase.b._data, [5.,5.,3.3,4.4,5.5]) @@ -226,13 +239,29 @@ class TestMRecords(NumpyTestCase): base = self.base.copy() mbase = base.view(mrecarray) mbase.harden_mask() - mbase[-2:] = 5 - assert_equal(mbase.a._data, [1,2,3,5,5]) - assert_equal(mbase.b._data, [1.1,2.2,3.3,5,5.5]) - assert_equal(mbase.c._data, ['one','two','three','5','five']) - assert_equal(mbase.a._mask, [0,1,0,0,1]) - assert_equal(mbase.b._mask, mbase.a._mask) - assert_equal(mbase.b._mask, mbase.c._mask) + try: + mbase[-2:] = (5,5,5) + assert_equal(mbase.a._data, [1,2,3,5,5]) + assert_equal(mbase.b._data, [1.1,2.2,3.3,5,5.5]) + assert_equal(mbase.c._data, ['one','two','three','5','five']) + assert_equal(mbase.a._mask, [0,1,0,0,1]) + assert_equal(mbase.b._mask, mbase.a._mask) + assert_equal(mbase.b._mask, mbase.c._mask) + except NotImplementedError: + # OK, not implemented yet... + pass + except AssertionError: + raise + else: + raise Exception("Flexible hard masks should be supported !") + # Not using a tuple should crash + try: + mbase[-2:] = 3 + except (NotImplementedError, TypeError): + pass + else: + raise TypeError("Should have expected a readable buffer object!") + def test_hardmask(self): "Test hardmask" @@ -241,11 +270,13 @@ class TestMRecords(NumpyTestCase): mbase.harden_mask() assert(mbase._hardmask) mbase._mask = nomask - assert_equal(mbase._mask, [0,1,0,0,1]) + assert_equal_records(mbase._mask, base._mask) mbase.soften_mask() assert(not mbase._hardmask) mbase._mask = nomask # So, the mask of a field is no longer set to nomask... + assert_equal_records(mbase._mask, + ma.make_mask_none(base.shape,base.dtype.names)) assert(ma.make_mask(mbase['b']._mask) is nomask) assert_equal(mbase['a']._mask,mbase['b']._mask) # |