[Numpy-svn] r4767 - in branches/maskedarray/numpy/ma: . tests
numpy-svn at scipy.org
numpy-svn at scipy.org
Fri Feb 1 18:40:40 EST 2008
Author: pierregm
Date: 2008-02-01 17:40:35 -0600 (Fri, 01 Feb 2008)
New Revision: 4767
Modified:
branches/maskedarray/numpy/ma/core.py
branches/maskedarray/numpy/ma/mrecords.py
branches/maskedarray/numpy/ma/tests/test_core.py
branches/maskedarray/numpy/ma/tests/test_mrecords.py
Log:
maskedarray.core:
tolist : make sure that a masked record is output as a tuple of None
maskedarray.mrecords:
* introduced mrecarray as the equivalent of recarray w/ fieldmask
* simplified fromarrays/fromrecords
Modified: branches/maskedarray/numpy/ma/core.py
===================================================================
--- branches/maskedarray/numpy/ma/core.py 2008-02-01 11:17:39 UTC (rev 4766)
+++ branches/maskedarray/numpy/ma/core.py 2008-02-01 23:40:35 UTC (rev 4767)
@@ -191,8 +191,8 @@
else:
fill_value = default_fill_value(dtype)
else:
- fval = numpy.resize(narray(fill_value,copy=False,dtype=object_),
- len(descr))
+ fill_value = narray(fill_value).tolist()
+ fval = numpy.resize(fill_value, len(descr))
if len(descr) > 1:
fill_value = [numpy.asarray(f).astype(d[1]).item()
for (f,d) in zip(fval, descr)]
@@ -2491,15 +2491,23 @@
if fill_value is not None:
return self.filled(fill_value).tolist()
result = self.filled().tolist()
- if self._mask is nomask:
+ # Set temps to save time when dealing w/ mrecarrays...
+ _mask = self._mask
+ if _mask is nomask:
return result
- if self.ndim == 0:
- return [None]
- elif self.ndim == 1:
- maskedidx = self._mask.nonzero()[0].tolist()
- [operator.setitem(result,i,None) for i in maskedidx]
+ nbdims = self.ndim
+ dtypesize = len(self.dtype)
+ if nbdims == 0:
+ return tuple([None]*dtypesize)
+ elif nbdims == 1:
+ maskedidx = _mask.nonzero()[0].tolist()
+ if dtypesize:
+ nodata = tuple([None]*dtypesize)
+ else:
+ nodata = None
+ [operator.setitem(result,i,nodata) for i in maskedidx]
else:
- for idx in zip(*[i.tolist() for i in self._mask.nonzero()]):
+ for idx in zip(*[i.tolist() for i in _mask.nonzero()]):
tmp = result
for i in idx[:-1]:
tmp = tmp[i]
Modified: branches/maskedarray/numpy/ma/mrecords.py
===================================================================
--- branches/maskedarray/numpy/ma/mrecords.py 2008-02-01 11:17:39 UTC (rev 4766)
+++ branches/maskedarray/numpy/ma/mrecords.py 2008-02-01 23:40:35 UTC (rev 4767)
@@ -1,35 +1,49 @@
"""mrecords
-Defines a class of record arrays supporting masked arrays.
+Defines the equivalent of recarrays for maskedarray.
+Masked arrays already support named fields, but masking works only by records.
+By comparison, mrecarrays support masking individual fields.
+
:author: Pierre Gerard-Marchant
"""
+#TODO: We should make sure that no field is called '_mask','mask','_fieldmask',
+#TODO: ...or whatever restricted keywords.
+#TODO: An idea would be to no bother in the first place, and then rename the
+#TODO: invalid fields with a trailing underscore...
+#TODO: Maybe we could just overload the parser function ?
+
+
__author__ = "Pierre GF Gerard-Marchant"
import sys
import types
import numpy
-from numpy import bool_, complex_, float_, int_, str_, object_
+from numpy import bool_, complex_, float_, int_, str_, object_, dtype
from numpy import array as narray
import numpy.core.numeric as numeric
import numpy.core.numerictypes as ntypes
from numpy.core.defchararray import chararray
-from numpy.core.records import find_duplicate
-
-from numpy.core.records import format_parser, record, recarray
+from numpy.core.records import find_duplicate, format_parser, record, recarray
from numpy.core.records import fromarrays as recfromarrays
+from numpy.core.records import fromrecords as recfromrecords
ndarray = numeric.ndarray
_byteorderconv = numpy.core.records._byteorderconv
_typestr = ntypes._typestr
import numpy.ma
-from numpy.ma import MaskedArray, masked, nomask, masked_array,\
- make_mask, mask_or, getmask, getmaskarray, filled
+from numpy.ma import MAError, MaskedArray, masked, nomask, masked_array,\
+ make_mask, mask_or, getdata, getmask, getmaskarray, filled
from numpy.ma.core import default_fill_value, masked_print_option
+_check_fill_value = numpy.ma.core._check_fill_value
import warnings
+__all__ = ['MaskedRecords','mrecarray',
+ 'fromarrays','fromrecords','fromtextfile','addfield',
+ ]
+
reserved_fields = ['_data','_mask','_fieldmask', 'dtype']
def _getformats(data):
@@ -80,7 +94,13 @@
return numeric.dtype(ndescr)
+def _get_fieldmask(self):
+ mdescr = [(n,'|b1') for n in self.dtype.names]
+ fdmask = numpy.empty(self.shape, dtype=mdescr)
+ fdmask.flat = tuple([False]*len(mdescr))
+ return fdmask
+
class MaskedRecords(MaskedArray, object):
"""
@@ -96,89 +116,131 @@
"""
_defaultfieldmask = nomask
_defaulthardmask = False
- def __new__(cls, data, mask=nomask, dtype=None,
- hard_mask=False, fill_value=None,
-# offset=0, strides=None,
+ #............................................
+ def __new__(cls, shape, dtype=None, buf=None, offset=0, strides=None,
formats=None, names=None, titles=None,
- byteorder=None, aligned=False):
- # Get the new descriptor ................
- if dtype is not None:
- descr = numeric.dtype(dtype)
+ byteorder=None, aligned=False,
+ mask=nomask, hard_mask=False, fill_value=None, keep_mask=True,
+ copy=False,
+ **options):
+ #
+ self = recarray.__new__(cls, shape, dtype=dtype, buf=buf, offset=offset,
+ strides=strides, formats=formats,
+ byteorder=byteorder, aligned=aligned,)
+# self = self.view(cls)
+ #
+ mdtype = [(k,'|b1') for (k,_) in self.dtype.descr]
+ if mask is nomask or not numpy.size(mask):
+ if not keep_mask:
+ self._fieldmask = tuple([False]*len(mdtype))
else:
- if formats is None:
- formats = _getformats(data)
- parsed = format_parser(formats, names, titles, aligned, byteorder)
- descr = parsed._descr
- if names is not None:
- descr = _checknames(descr,names)
- _names = descr.names
- mdescr = [(n,'|b1') for n in _names]
- # get the shape .........................
- try:
- shape = numeric.asarray(data[0]).shape
- except IndexError:
- shape = len(data.dtype)
- if isinstance(shape, int):
- shape = (shape,)
- # Construct the _data recarray ..........
- if isinstance(data, record):
- _data = numeric.asarray(data).view(recarray)
- _fieldmask = mask
- elif isinstance(data, MaskedRecords):
- _data = data._data
- _fieldmask = data._fieldmask
- elif isinstance(data, recarray):
- _data = data
- if mask is nomask:
- _fieldmask = data.astype(mdescr)
- _fieldmask.flat = tuple([False]*len(mdescr))
+ mask = narray(mask, copy=copy)
+ if mask.shape != self.shape:
+ (nd, nm) = (self.size, mask.size)
+ if nm == 1:
+ mask = numpy.resize(mask, self.shape)
+ elif nm == nd:
+ mask = numpy.reshape(mask, self.shape)
+ else:
+ msg = "Mask and data not compatible: data size is %i, "+\
+ "mask size is %i."
+ raise MAError(msg % (nd, nm))
+ copy = True
+ if not keep_mask:
+ self.__setmask__(mask)
+ self._sharedmask = True
else:
- _fieldmask = mask
- elif (isinstance(data, (tuple, numpy.void)) or\
- hasattr(data,'__len__') and isinstance(data[0], (tuple, numpy.void))):
- data = numeric.array(data, dtype=descr).view(recarray)
- _data = data
- if mask is nomask:
- _fieldmask = data.astype(mdescr)
- _fieldmask.flat = tuple([False]*len(mdescr))
- else:
- _fieldmask = mask
- else:
- _data = recarray(shape, dtype=descr)
- _fieldmask = recarray(shape, dtype=mdescr)
- for (n,v) in zip(_names, data):
- _data[n] = numeric.asarray(v).view(ndarray)
- _fieldmask[n] = getmaskarray(v)
- #........................................
- _data = _data.view(cls)
- _data._fieldmask = _fieldmask
- _data._hardmask = hard_mask
- if fill_value is None:
- _data._fill_value = [default_fill_value(numeric.dtype(d[1]))
- for d in descr.descr]
- else:
- _data._fill_value = fill_value
- return _data
-
+ if mask.dtype == mdtype:
+ _fieldmask = mask
+ else:
+ _fieldmask = narray([tuple([m]*len(mdtype)) for m in mask],
+ dtype=mdtype)
+ self._fieldmask = _fieldmask
+ return self
+ #......................................................
def __array_finalize__(self,obj):
- if isinstance(obj, MaskedRecords):
- self.__dict__.update(_fieldmask=obj._fieldmask,
- _hardmask=obj._hardmask,
- _fill_value=obj._fill_value
- )
- else:
- self.__dict__.update(_fieldmask = nomask,
- _hardmask = False,
- fill_value = None
- )
+ # 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]
+ _fieldmask = numpy.empty(self.shape, dtype=mdescr).view(recarray)
+ _fieldmask.flat = tuple([False]*len(mdescr))
+ # Update some of the attributes
+ attrdict = dict(_fieldmask=_fieldmask,
+ _hardmask=getattr(obj,'_hardmask',False),
+ _fill_value=getattr(obj,'_fill_value',None))
+ self.__dict__.update(attrdict)
+ # Finalize as a regular maskedarray .....
+ # Note: we can't call MaskedArray.__array_finalize__, it chokes pickling
+ self._update_from(obj)
+ # Update special attributes ...
+ self._basedict = getattr(obj, '_basedict', getattr(obj, '__dict__', None))
+ if self._basedict is not None:
+ self.__dict__.update(self._basedict)
return
-
+ #......................................................
def _getdata(self):
"Returns the data as a recarray."
return self.view(recarray)
_data = property(fget=_getdata)
+ #......................................................
+ def __setmask__(self, mask):
+ "Sets the mask and update the fieldmask."
+ names = self.dtype.names
+ fmask = self.__dict__['_fieldmask']
+ 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 = property(fget=_getmask, fset=_setmask)
+ #......................................................
+ def get_fill_value(self):
+ """Return the filling value.
+ """
+ if self._fill_value is None:
+ ddtype = self.dtype
+ fillval = _check_fill_value(None, ddtype)
+ self._fill_value = narray(tuple(fillval), dtype=ddtype)
+ return self._fill_value
+
+ def set_fill_value(self, value=None):
+ """Set the filling value to value.
+
+ If value is None, use a default based on the data type.
+
+ """
+ ddtype = self.dtype
+ fillval = _check_fill_value(value, ddtype)
+ self._fill_value = narray(tuple(fillval), dtype=ddtype)
+
+ fill_value = property(fget=get_fill_value, fset=set_fill_value,
+ doc="Filling value.")
#......................................................
+ def __len__(self):
+ "Returns the length"
+ # We have more than one record
+ if self.ndim:
+ 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:
@@ -215,7 +277,15 @@
exctype, value = sys.exc_info()[:2]
raise exctype, value
else:
- if attr not in list(self.dtype.names) + ['_mask','mask']:
+ # Get the list of names ......
+ _names = self.dtype.names
+ if _names is None:
+ _names = []
+ else:
+ _names = list(_names)
+ _names += ['_mask','mask']
+ # Check the attribute
+ if attr not in _names:
return ret
if newattr: # We just added this one
try: # or this setattr worked on an internal
@@ -227,14 +297,26 @@
base_fmask = self._fieldmask
_names = self.dtype.names
if attr in _names:
- fval = filled(val)
- mval = getmaskarray(val)
+ if val is masked:
+ fval = self.fill_value[attr]
+ mval = True
+ 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
elif attr == '_mask':
+ #FIXME: We should check for self._harmask over there.
+# if self._hardmask:
+# val = make_mask(val)
+# if val is not nomask:
+## mval = getmaskarray(val)
+# for k in _names:
+# m = mask_or(val, base_fmask.__getattr__(k))
+# base_fmask.__setattr__(k, m)
self.__setmask__(val)
return
#............................................
@@ -242,30 +324,29 @@
"""Returns all the fields sharing the same fieldname base.
The fieldname base is either `_data` or `_mask`."""
_localdict = self.__dict__
+ _fieldmask = _localdict['_fieldmask']
_data = self._data
# We want a field ........
if isinstance(indx, basestring):
obj = _data[indx].view(MaskedArray)
- obj._set_mask(_localdict['_fieldmask'][indx])
+ obj._set_mask(_fieldmask[indx])
# Force to nomask if the mask is empty
if not obj._mask.any():
obj._mask = nomask
+ # Force to masked if the mask is True
+ if not obj.ndim and obj._mask:
+ return masked
return obj
# We want some elements ..
# First, the data ........
- obj = ndarray.__getitem__(self, indx)
- if isinstance(obj, numpy.void):
- obj = self.__class__(obj, dtype=self.dtype)
- else:
- obj = obj.view(type(self))
- obj._fieldmask = numpy.asarray(_localdict['_fieldmask'][indx]).view(recarray)
+ obj = narray(_data[indx], copy=False).view(mrecarray)
+ obj._fieldmask = narray(_fieldmask[indx], copy=False).view(recarray)
return obj
- #............................................
+ #....
def __setitem__(self, indx, value):
"Sets the given record to value."
MaskedArray.__setitem__(self, indx, value)
-
-
+ #............................................
def __setslice__(self, i, j, value):
"Sets the slice described by [i,j] to `value`."
_localdict = self.__dict__
@@ -295,31 +376,6 @@
d[n][i:j][~mval] = dval[~mval]
m[n][i:j] = mask_or(m[n][i:j], mval)
self._fieldmask = m
-
- #.....................................................
- def __setmask__(self, mask):
- "Sets the mask."
- names = self.dtype.names
- fmask = self.__dict__['_fieldmask']
- newmask = make_mask(mask, copy=False)
-# self.unshare_mask()
- if self._hardmask:
- for n in names:
- fmask[n].__ior__(newmask)
- else:
- for n in names:
- fmask[n].flat = newmask
- return
-
- def _getmask(self):
- """Returns 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)
-
- _setmask = __setmask__
- _mask = property(fget=_getmask, fset=_setmask)
-
#......................................................
def __str__(self):
"Calculates the string representation."
@@ -331,14 +387,14 @@
mstr = ["%s" % ",".join([str(i) for i in s])
for s in zip([getattr(self,f) for f in self.dtype.names])]
return "(%s)" % ", ".join(mstr)
-
+ #
def __repr__(self):
"Calculates the repr representation."
_names = self.dtype.names
fmt = "%%%is : %%s" % (max([len(n) for n in _names])+4,)
reprstr = [fmt % (f,getattr(self,f)) for f in self.dtype.names]
reprstr.insert(0,'masked_records(')
- reprstr.extend([fmt % (' fill_value', self._fill_value),
+ reprstr.extend([fmt % (' fill_value', self.fill_value),
' )'])
return str("\n".join(reprstr))
#......................................................
@@ -355,11 +411,11 @@
return ndarray.view(self, obj)
#......................................................
def filled(self, fill_value=None):
- """Returns an array of the same class as ``_data``, with masked values
-filled with ``fill_value``. If ``fill_value`` is None, ``self.fill_value`` is
-used instead.
+ """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.
+ Subclassing is preserved.
"""
_localdict = self.__dict__
@@ -369,7 +425,7 @@
return d
#
if fill_value is None:
- value = _localdict['_fill_value']
+ value = _check_fill_value(_localdict['_fill_value'],self.dtype)
else:
value = fill_value
if numeric.size(value) == 1:
@@ -383,168 +439,213 @@
numpy.putmask(numeric.asarray(result[n]),
numeric.asarray(fm[n]), v)
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__
- return MaskedRecords(self._data.copy(),
- mask=_localdict['_fieldmask'].copy(),
- dtype=self.dtype)
- #.............................................
+ 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.
+ Data items are converted to the nearest compatible Python
+ type. Masked values are converted to fill_value. If
+ fill_value is None, the corresponding entries in the output
+ list will be ``None``.
+ """
+ if fill_value is not None:
+ return self.filled(fill_value).tolist()
+ result = narray(self.filled().tolist(), dtype=object)
+ mask = narray(self._fieldmask.tolist())
+ result[mask] = None
+ return [tuple(r) for r in result]
+ #--------------------------------------------
+ # Pickling
+ def __getstate__(self):
+ """Return the internal state of the masked array, for pickling purposes.
+
+ """
+ state = (1,
+ self.shape,
+ self.dtype,
+ self.flags.fnc,
+ self._data.tostring(),
+ self._fieldmask.tostring(),
+ self._fill_value,
+ )
+ return state
+ #
+ def __setstate__(self, state):
+ """Restore the internal state of the masked array, for pickling purposes.
+ ``state`` is typically the output of the ``__getstate__`` output, and is a
+ 5-tuple:
+
+ - class name
+ - a tuple giving the shape of the data
+ - a typecode for the data
+ - a binary string for the data
+ - a binary string for the mask.
+
+ """
+ (ver, shp, typ, isf, raw, msk, flv) = state
+ ndarray.__setstate__(self, (shp, typ, isf, raw))
+ mdtype = dtype([(k,bool_) for (k,_) in self.dtype.descr])
+ self._fieldmask.__setstate__((shp, mdtype, isf, msk))
+ self.fill_value = flv
+ #
+ def __reduce__(self):
+ """Return a 3-tuple for pickling a MaskedArray.
+
+ """
+ return (_mrreconstruct,
+ (self.__class__, self._baseclass, (0,), 'b', ),
+ self.__getstate__())
+
+def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
+ """Internal function that builds a new MaskedArray from the
+ information stored in a pickle.
+
+ """
+ _data = ndarray.__new__(baseclass, baseshape, basetype).view(subtype)
+# _data._mask = ndarray.__new__(ndarray, baseshape, 'b1')
+# return _data
+ _mask = ndarray.__new__(ndarray, baseshape, 'b1')
+ return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
+
+mrecarray = MaskedRecords
+
#####---------------------------------------------------------------------------
#---- --- Constructors ---
#####---------------------------------------------------------------------------
def fromarrays(arraylist, dtype=None, shape=None, formats=None,
- names=None, titles=None, aligned=False, byteorder=None):
+ names=None, titles=None, aligned=False, byteorder=None,
+ fill_value=None):
"""Creates a mrecarray from a (flat) list of masked arrays.
-*Parameters*:
- arraylist : {sequence}
+ Parameters
+ ----------
+ arraylist : sequence
A list of (masked) arrays. Each element of the sequence is first converted
to a masked array if needed. If a 2D array is passed as argument, it is
processed line by line
- dtype : {numeric.dtype}
+ dtype : numeric.dtype
Data type descriptor.
- {shape} : {integer}
- Number of records. If None, ``shape`` is defined from the shape of the
+ shape : integer
+ Number of records. If None, shape is defined from the shape of the
first array in the list.
- formats : {sequence}
+ formats : sequence
Sequence of formats for each individual field. If None, the formats will
be autodetected by inspecting the fields and selecting the highest dtype
possible.
- names : {sequence}
+ names : sequence
Sequence of the names of each field.
- -titles : {sequence}
+ titles : sequence
(Description to write)
- aligned : {boolean}
+ aligned : boolean
(Description to write, not used anyway)
- byteorder: {boolean}
+ byteorder: boolean
(Description to write, not used anyway)
+ fill_value : sequence
+ Sequence of data to be used as filling values.
-*Notes*:
+ Notes
+ -----
Lists of tuples should be preferred over lists of lists for faster processing.
"""
- arraylist = [masked_array(x) for x in arraylist]
- # Define/check the shape.....................
- if shape is None or shape == 0:
- shape = arraylist[0].shape
- if isinstance(shape, int):
- shape = (shape,)
- # Define formats from scratch ...............
- if formats is None and dtype is None:
- formats = _getformats(arraylist)
- # Define the dtype ..........................
- if dtype is not None:
- descr = numeric.dtype(dtype)
- _names = descr.names
- else:
- parsed = format_parser(formats, names, titles, aligned, byteorder)
- _names = parsed._names
- descr = parsed._descr
- # Determine shape from data-type.............
- if len(descr) != len(arraylist):
- msg = "Mismatch between the number of fields (%i) and the number of "\
- "arrays (%i)"
- raise ValueError, msg % (len(descr), len(arraylist))
- d0 = descr[0].shape
- nn = len(d0)
- if nn > 0:
- shape = shape[:-nn]
- # Make sure the shape is the correct one ....
- for k, obj in enumerate(arraylist):
- nn = len(descr[k].shape)
- testshape = obj.shape[:len(obj.shape)-nn]
- if testshape != shape:
- raise ValueError, "Array-shape mismatch in array %d" % k
- # Reconstruct the descriptor, by creating a _data and _mask version
- return MaskedRecords(arraylist, dtype=descr)
+ datalist = [getdata(x) for x in arraylist]
+ masklist = [getmaskarray(x) for x in arraylist]
+ _array = recfromarrays(datalist,
+ dtype=dtype, shape=shape, formats=formats,
+ names=names, titles=titles, aligned=aligned,
+ byteorder=byteorder).view(mrecarray)
+ _array._fieldmask[:] = zip(*masklist)
+ if fill_value is not None:
+ _array.fill_value = fill_value
+ return _array
+
+
#..............................................................................
def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None,
- titles=None, aligned=False, byteorder=None):
+ titles=None, aligned=False, byteorder=None,
+ fill_value=None, mask=nomask):
"""Creates a MaskedRecords from a list of records.
-*Parameters*:
- arraylist : {sequence}
+ Parameters
+ ----------
+ arraylist : sequence
A list of (masked) arrays. Each element of the sequence is first converted
to a masked array if needed. If a 2D array is passed as argument, it is
processed line by line
- dtype : {numeric.dtype}
+ dtype : numeric.dtype
Data type descriptor.
- {shape} : {integer}
+ shape : integer
Number of records. If None, ``shape`` is defined from the shape of the
first array in the list.
- formats : {sequence}
+ formats : sequence
Sequence of formats for each individual field. If None, the formats will
be autodetected by inspecting the fields and selecting the highest dtype
possible.
- names : {sequence}
+ names : sequence
Sequence of the names of each field.
- -titles : {sequence}
+ titles : sequence
(Description to write)
- aligned : {boolean}
+ aligned : boolean
(Description to write, not used anyway)
- byteorder: {boolean}
+ byteorder: boolean
(Description to write, not used anyway)
+ fill_value : sequence
+ Sequence of data to be used as filling values.
+ mask : sequence or boolean.
+ External mask to apply on the data.
*Notes*:
Lists of tuples should be preferred over lists of lists for faster processing.
"""
- # reclist is in fact a mrecarray .................
- if isinstance(reclist, MaskedRecords):
- mdescr = reclist.dtype
- shape = reclist.shape
- return MaskedRecords(reclist, dtype=mdescr)
- # No format, no dtype: create from to arrays .....
+ # Grab the initial _fieldmask, if needed:
+ _fieldmask = getattr(reclist, '_fieldmask', None)
+ # Get the list of records.....
nfields = len(reclist[0])
- if formats is None and dtype is None: # slower
- if isinstance(reclist, recarray):
- arrlist = [reclist.field(i) for i in range(len(reclist.dtype))]
- if names is None:
- names = reclist.dtype.names
+ if isinstance(reclist, ndarray):
+ # Make sure we don't have some hidden mask
+ if isinstance(reclist,MaskedArray):
+ reclist = reclist.filled().view(ndarray)
+ # Grab the initial dtype, just in case
+ if dtype is None:
+ dtype = reclist.dtype
+ reclist = reclist.tolist()
+ mrec = recfromrecords(reclist, dtype=dtype, shape=shape, formats=formats,
+ names=names, titles=titles,
+ aligned=aligned, byteorder=byteorder).view(mrecarray)
+ # Set the fill_value if needed
+ if fill_value is not None:
+ mrec.fill_value = fill_value
+ # Now, let's deal w/ the mask
+ if mask is not nomask:
+ mask = narray(mask, copy=False)
+ maskrecordlength = len(mask.dtype)
+ if maskrecordlength:
+ mrec._fieldmask.flat = mask
+ elif len(mask.shape) == 2:
+ mrec._fieldmask.flat = [tuple(m) for m in mask]
else:
- obj = numeric.array(reclist,dtype=object)
- arrlist = [numeric.array(obj[...,i].tolist())
- for i in xrange(nfields)]
- return MaskedRecords(arrlist, formats=formats, names=names,
- titles=titles, aligned=aligned, byteorder=byteorder)
- # Construct the descriptor .......................
- if dtype is not None:
- descr = numeric.dtype(dtype)
- _names = descr.names
- else:
- parsed = format_parser(formats, names, titles, aligned, byteorder)
- _names = parsed._names
- descr = parsed._descr
+ mrec._mask = mask
+ if _fieldmask is not None:
+ mrec._fieldmask[:] = _fieldmask
+ return mrec
- try:
- retval = numeric.array(reclist, dtype = descr).view(recarray)
- except TypeError: # list of lists instead of list of tuples
- if (shape is None or shape == 0):
- shape = len(reclist)*2
- if isinstance(shape, (int, long)):
- shape = (shape*2,)
- if len(shape) > 1:
- raise ValueError, "Can only deal with 1-d array."
- retval = recarray(shape, mdescr)
- for k in xrange(retval.size):
- retval[k] = tuple(reclist[k])
- return MaskedRecords(retval, dtype=descr)
- else:
- if shape is not None and retval.shape != shape:
- retval.shape = shape
- #
- return MaskedRecords(retval, dtype=descr)
-
def _guessvartypes(arr):
"""Tries to guess the dtypes of the str_ ndarray `arr`, by testing element-wise
conversion. Returns a list of dtypes.
@@ -648,7 +749,7 @@
_mask = (_variables.T == missingchar)
_datalist = [masked_array(a,mask=m,dtype=t)
for (a,m,t) in zip(_variables.T, _mask, vartypes)]
- return MaskedRecords(_datalist, dtype=mdescr)
+ return fromarrays(_datalist, dtype=mdescr)
#....................................................................
def addfield(mrecord, newfield, newfieldname=None):
@@ -685,28 +786,6 @@
newdata._fieldmask = newmask
return newdata
-################################################################################
-if __name__ == '__main__':
- import numpy as N
- from numpy.ma.testutils import assert_equal
- if 1:
- d = N.arange(5)
- m = numpy.ma.make_mask([1,0,0,1,1])
- base_d = N.r_[d,d[::-1]].reshape(2,-1).T
- base_m = N.r_[[m, m[::-1]]].T
- base = masked_array(base_d, mask=base_m).T
- mrecord = fromarrays(base,dtype=[('a',N.float_),('b',N.float_)])
- mrec = MaskedRecords(mrecord.copy())
- #
- if 1:
- mrec = mrec.copy()
- mrec.harden_mask()
- assert(mrec._hardmask)
- mrec._mask = nomask
- assert_equal(mrec._mask, N.r_[[m,m[::-1]]].all(0))
- mrec.soften_mask()
- assert(not mrec._hardmask)
- mrec.mask = nomask
- tmp = mrec['b']._mask
- assert(mrec['b']._mask is nomask)
- assert_equal(mrec['a']._mask,mrec['b']._mask)
+###############################################################################
+
+
Modified: branches/maskedarray/numpy/ma/tests/test_core.py
===================================================================
--- branches/maskedarray/numpy/ma/tests/test_core.py 2008-02-01 11:17:39 UTC (rev 4766)
+++ branches/maskedarray/numpy/ma/tests/test_core.py 2008-02-01 23:40:35 UTC (rev 4767)
@@ -1347,7 +1347,16 @@
assert_equal(xlist[0],[0,None,2,3])
assert_equal(xlist[1],[4,5,6,7])
assert_equal(xlist[2],[8,9,None,11])
+ # Make sure a masked record is output as a tuple of None
+ x = array(zip([1,2,3],
+ [1.1,2.2,3.3],
+ ['one','two','thr']),
+ dtype=[('a',int_),('b',float_),('c','|S8')])
+ x[-1] = masked
+ 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]])
Modified: branches/maskedarray/numpy/ma/tests/test_mrecords.py
===================================================================
--- branches/maskedarray/numpy/ma/tests/test_mrecords.py 2008-02-01 11:17:39 UTC (rev 4766)
+++ branches/maskedarray/numpy/ma/tests/test_mrecords.py 2008-02-01 23:40:35 UTC (rev 4767)
@@ -1,33 +1,35 @@
# pylint: disable-msg=W0611, W0612, W0511,R0201
-"""Tests suite for mrecarray.
+"""Tests suite for mrecords.
:author: Pierre Gerard-Marchant
:contact: pierregm_at_uga_dot_edu
-:version: $Id: test_mrecords.py 3473 2007-10-29 15:18:13Z jarrod.millman $
"""
__author__ = "Pierre GF Gerard-Marchant ($Author: jarrod.millman $)"
-__version__ = '1.0'
__revision__ = "$Revision: 3473 $"
__date__ = '$Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $'
import types
import numpy as N
-import numpy.core.fromnumeric as fromnumeric
+from numpy import recarray, bool_, int_, float_
+from numpy import array as narray
+from numpy.core.records import fromrecords as recfromrecords
+from numpy.core.records import fromarrays as recfromarrays
+import numpy.core.fromnumeric as fromnumeric_
from numpy.testing import NumpyTest, NumpyTestCase
from numpy.testing.utils import build_err_msg
import numpy.ma.testutils
-from numpy.ma.testutils import *
+from numpy.ma.testutils import assert_equal, assert_equal_records
import numpy.ma
-from numpy.ma import masked_array, masked, nomask
+from numpy.ma import masked_array, masked, nomask, getdata, getmaskarray
#import numpy.ma.mrecords
#from numpy.ma.mrecords import mrecarray, fromarrays, fromtextfile, fromrecords
import numpy.ma.mrecords
-from numpy.ma.mrecords import MaskedRecords, \
+from numpy.ma.mrecords import MaskedRecords, mrecarray,\
fromarrays, fromtextfile, fromrecords, addfield
#..............................................................................
@@ -39,111 +41,275 @@
def setup(self):
"Generic setup"
- d = N.arange(5)
- m = numpy.ma.make_mask([1,0,0,1,1])
- base_d = N.r_[d,d[::-1]].reshape(2,-1).T
- base_m = N.r_[[m, m[::-1]]].T
- base = masked_array(base_d, mask=base_m)
- mrecord = fromarrays(base.T, dtype=[('a',N.float_),('b',N.float_)])
- self.data = [d, m, mrecord]
+ 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')]
+ mask = [0,1,0,0,1]
+ self.base = masked_array(zip(ilist,flist,slist), mask=mask, dtype=ddtype)
+
+ def test_byview(self):
+ "Test creation by view"
+ base = self.base
+ mbase = base.view(mrecarray)
+ assert_equal(mbase._mask, base._mask)
+ assert isinstance(mbase._data, recarray)
+ assert_equal_records(mbase._data, base._data.view(recarray))
+ for field in ('a','b','c'):
+ assert_equal(base[field], mbase[field])
+ assert_equal_records(mbase.view(mrecarray), mbase)
def test_get(self):
"Tests fields retrieval"
- [d, m, mrec] = self.data
- mrec = mrec.copy()
- assert_equal(mrec.a, masked_array(d,mask=m))
- assert_equal(mrec.b, masked_array(d[::-1],mask=m[::-1]))
- assert((mrec._fieldmask == N.core.records.fromarrays([m, m[::-1]], dtype=mrec._fieldmask.dtype)).all())
- assert_equal(mrec._mask, N.r_[[m,m[::-1]]].all(0))
- assert_equal(mrec.a[1], mrec[1].a)
- #
- assert(isinstance(mrec[:2], MaskedRecords))
- assert_equal(mrec[:2]['a'], d[:2])
+ base = self.base.copy()
+ mbase = base.view(mrecarray)
+ # As fields..........
+ for field in ('a','b','c'):
+ assert_equal(getattr(mbase,field), mbase[field])
+ assert_equal(base[field], mbase[field])
+ # as elements .......
+ mbase_first = mbase[0]
+ 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)
+ assert_equal(mbase_first._fieldmask.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)
+ assert_equal(mbase_last._fieldmask.item(), (True, True, True))
+ assert_equal(mbase_last['a'], mbase['a'][-1])
+ assert (mbase_last['a'] is masked)
+ # as slice ..........
+ mbase_sl = mbase[:2]
+ assert isinstance(mbase_sl, mrecarray)
+ assert_equal(mbase_sl.dtype, mbase.dtype)
+ assert_equal(mbase_sl._mask, [0,1])
+ assert_equal_records(mbase_sl, base[:2].view(mrecarray))
+ for field in ('a','b','c'):
+ assert_equal(getattr(mbase_sl,field), base[:2][field])
- def test_set(self):
- "Tests setting fields/attributes."
- [d, m, mrecord] = self.data
- mrecord.a._data[:] = 5
- assert_equal(mrecord['a']._data, [5,5,5,5,5])
- mrecord.a = 1
- assert_equal(mrecord['a']._data, [1]*5)
- assert_equal(getmaskarray(mrecord['a']), [0]*5)
- mrecord.b = masked
- assert_equal(mrecord.b.mask, [1]*5)
- assert_equal(getmaskarray(mrecord['b']), [1]*5)
- mrecord._mask = masked
- assert_equal(getmaskarray(mrecord['b']), [1]*5)
- assert_equal(mrecord['a']._mask, mrecord['b']._mask)
- mrecord._mask = nomask
- assert_equal(getmaskarray(mrecord['b']), [0]*5)
- assert_equal(mrecord['a']._mask, mrecord['b']._mask)
+ def test_set_fields(self):
+ "Tests setting fields."
+ base = self.base.copy()
+ mbase = base.view(mrecarray)
+ mbase = mbase.copy()
+ mbase.fill_value = (999999,1e20,'N/A')
+ # Change the data, the mask should be conserved
+ mbase.a._data[:] = 5
+ assert_equal(mbase['a']._data, [5,5,5,5,5])
+ assert_equal(mbase['a']._mask, [0,1,0,0,1])
+ # Change the elements, and the mask will follow
+ mbase.a = 1
+ assert_equal(mbase['a']._data, [1]*5)
+ assert_equal(getmaskarray(mbase['a']), [0]*5)
+ assert_equal(mbase._mask, [False]*5)
+ assert_equal(mbase._fieldmask.tolist(),
+ narray([(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
+ assert_equal(mbase.c.mask, [1]*5)
+ assert_equal(getmaskarray(mbase['c']), [1]*5)
+ assert_equal(getdata(mbase['c']), ['N/A']*5)
+ assert_equal(mbase._fieldmask.tolist(),
+ narray([(0,0,1),(0,1,1),(0,0,1),(0,0,1),(0,1,1)],
+ dtype=bool_))
+ # Set fields by slices .......................
+ mbase = base.view(mrecarray).copy()
+ mbase.a[3:] = 5
+ assert_equal(mbase.a, [1,2,3,5,5])
+ assert_equal(mbase.a._mask, [0,1,0,0,0])
+ mbase.b[3:] = masked
+ assert_equal(mbase.b, base['b'])
+ assert_equal(mbase.b._mask, [0,1,0,1,1])
+ #
+ def test_set_mask(self):
+ base = self.base.copy()
+ mbase = base.view(mrecarray)
+ # Set the mask to True .......................
+ mbase._mask = masked
+ assert_equal(getmaskarray(mbase['b']), [1]*5)
+ assert_equal(mbase['a']._mask, mbase['b']._mask)
+ assert_equal(mbase['a']._mask, mbase['c']._mask)
+ assert_equal(mbase._fieldmask.tolist(),
+ narray([(1,1,1)]*5,
+ dtype=bool_))
+ # Delete the mask ............................
+ mbase._mask = nomask
+ assert_equal(getmaskarray(mbase['c']), [0]*5)
+ assert_equal(mbase._fieldmask.tolist(),
+ narray([(0,0,0)]*5,
+ dtype=bool_))
+ #
+ def test_set_elements(self):
+ base = self.base.copy()
+ mbase = base.view(mrecarray)
+ # Set an element to mask .....................
+ mbase[-2] = masked
+ assert_equal(mbase._fieldmask.tolist(),
+ narray([(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])
+ # Set slices .................................
+ mbase = base.view(mrecarray).copy()
+ mbase[:2] = 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])
+ assert_equal(mbase.b._mask, [0,0,0,0,1])
+ assert_equal(mbase.c._data, ['5','5','three','four','five'])
+ assert_equal(mbase.b._mask, [0,0,0,0,1])
#
- def test_setfields(self):
- "Tests setting fields."
- [d, m, mrecord] = self.data
- mrecord.a[3:] = 5
- assert_equal(mrecord.a, [0,1,2,5,5])
- assert_equal(mrecord.a._mask, [1,0,0,0,0])
- #
- mrecord.b[3:] = masked
- assert_equal(mrecord.b, [4,3,2,1,0])
- assert_equal(mrecord.b._mask, [1,1,0,1,1])
-
- def test_setslices(self):
- "Tests setting slices."
- [d, m, mrec] = self.data
- mrec[:2] = 5
- assert_equal(mrec.a._data, [5,5,2,3,4])
- assert_equal(mrec.b._data, [5,5,2,1,0])
- assert_equal(mrec.a._mask, [0,0,0,1,1])
- assert_equal(mrec.b._mask, [0,0,0,0,1])
- #
- mrec[:2] = masked
- assert_equal(mrec._mask, [1,1,0,0,1])
- mrec[-2] = masked
- assert_equal(mrec._mask, [1,1,0,1,1])
- #
+ mbase = base.view(mrecarray).copy()
+ mbase[:2] = masked
+ assert_equal(mbase.a._data, [1,2,3,4,5])
+ assert_equal(mbase.a._mask, [1,1,0,0,1])
+ assert_equal(mbase.b._data, [1.1,2.2,3.3,4.4,5.5])
+ assert_equal(mbase.b._mask, [1,1,0,0,1])
+ assert_equal(mbase.c._data, ['one','two','three','four','five'])
+ assert_equal(mbase.b._mask, [1,1,0,0,1])
+ #
def test_setslices_hardmask(self):
"Tests setting slices w/ hardmask."
- [d, m, mrec] = self.data
- mrec.harden_mask()
- mrec[-2:] = 5
- assert_equal(mrec.a._data, [0,1,2,3,4])
- assert_equal(mrec.b._data, [4,3,2,5,0])
- assert_equal(mrec.a._mask, [1,0,0,1,1])
- assert_equal(mrec.b._mask, [1,1,0,0,1])
+ 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)
def test_hardmask(self):
"Test hardmask"
- [d, m, mrec] = self.data
- mrec = mrec.copy()
- mrec.harden_mask()
- assert(mrec._hardmask)
- mrec._mask = nomask
- assert_equal(mrec._mask, N.r_[[m,m[::-1]]].all(0))
- mrec.soften_mask()
- assert(not mrec._hardmask)
- mrec._mask = nomask
- assert(mrec['b']._mask is nomask)
- assert_equal(mrec['a']._mask,mrec['b']._mask)
+ base = self.base.copy()
+ mbase = base.view(mrecarray)
+ mbase.harden_mask()
+ assert(mbase._hardmask)
+ mbase._mask = nomask
+ assert_equal(mbase._mask, [0,1,0,0,1])
+ mbase.soften_mask()
+ assert(not mbase._hardmask)
+ mbase._mask = nomask
+ assert(mbase['b']._mask is nomask)
+ assert_equal(mbase['a']._mask,mbase['b']._mask)
+ #
+ def test_pickling(self):
+ "Test pickling"
+ import cPickle
+ base = self.base.copy()
+ mrec = base.view(mrecarray)
+ _ = cPickle.dumps(mrec)
+ mrec_ = cPickle.loads(_)
+ assert_equal(mrec_.dtype, mrec.dtype)
+ assert_equal_records(mrec_._data, mrec._data)
+ assert_equal(mrec_._mask, mrec._mask)
+ assert_equal_records(mrec_._fieldmask, mrec._fieldmask)
+ #
+ def test_filled(self):
+ "Test filling the array"
+ _a = masked_array([1,2,3],mask=[0,0,1],dtype=int_)
+ _b = masked_array([1.1,2.2,3.3],mask=[0,0,1],dtype=float_)
+ _c = masked_array(['one','two','three'],mask=[0,0,1],dtype='|S8')
+ ddtype = [('a',int_),('b',float_),('c','|S8')]
+ mrec = fromarrays([_a,_b,_c], dtype=ddtype,
+ fill_value=(99999,99999.,'N/A'))
+ mrecfilled = mrec.filled()
+ assert_equal(mrecfilled['a'], narray((1,2,99999), dtype=int_))
+ assert_equal(mrecfilled['b'], narray((1.1,2.2,99999.), dtype=float_))
+ assert_equal(mrecfilled['c'], narray(('one','two','N/A'), dtype='|S8'))
+ #
+ def test_tolist(self):
+ "Test tolist."
+ _a = masked_array([1,2,3],mask=[0,0,1],dtype=int_)
+ _b = masked_array([1.1,2.2,3.3],mask=[0,0,1],dtype=float_)
+ _c = masked_array(['one','two','three'],mask=[1,0,0],dtype='|S8')
+ ddtype = [('a',int_),('b',float_),('c','|S8')]
+ mrec = fromarrays([_a,_b,_c], dtype=ddtype,
+ fill_value=(99999,99999.,'N/A'))
+ #
+ assert_equal(mrec.tolist(),
+ [(1,1.1,None),(2,2.2,'two'),(None,None,'three')])
+################################################################################
+class TestMRecordsImport(NumpyTestCase):
+ "Base test class for MaskedArrays."
+ def __init__(self, *args, **kwds):
+ NumpyTestCase.__init__(self, *args, **kwds)
+ self.setup()
+
+ def setup(self):
+ "Generic setup"
+ _a = masked_array([1,2,3],mask=[0,0,1],dtype=int_)
+ _b = masked_array([1.1,2.2,3.3],mask=[0,0,1],dtype=float_)
+ _c = masked_array(['one','two','three'],mask=[0,0,1],dtype='|S8')
+ ddtype = [('a',int_),('b',float_),('c','|S8')]
+ mrec = fromarrays([_a,_b,_c], dtype=ddtype,
+ fill_value=(99999,99999.,'N/A'))
+ nrec = recfromarrays((_a.data,_b.data,_c.data), dtype=ddtype)
+ self.data = (mrec, nrec, ddtype)
+
+ def test_fromarrays(self):
+ _a = masked_array([1,2,3],mask=[0,0,1],dtype=int_)
+ _b = masked_array([1.1,2.2,3.3],mask=[0,0,1],dtype=float_)
+ _c = masked_array(['one','two','three'],mask=[0,0,1],dtype='|S8')
+ (mrec, nrec, _) = self.data
+ for (f,l) in zip(('a','b','c'),(_a,_b,_c)):
+ assert_equal(getattr(mrec,f)._mask, l._mask)
+
+
def test_fromrecords(self):
- "Test from recarray."
- [d, m, mrec] = self.data
- nrec = N.core.records.fromarrays(N.r_[[d,d[::-1]]],
- dtype=[('a',N.float_),('b',N.float_)])
- #....................
- mrecfr = fromrecords(nrec)
- assert_equal(mrecfr.a, mrec.a)
- assert_equal(mrecfr.dtype, mrec.dtype)
- #....................
- tmp = mrec[::-1] #.tolist()
- mrecfr = fromrecords(tmp)
- assert_equal(mrecfr.a, mrec.a[::-1])
- #....................
- mrecfr = fromrecords(nrec.tolist(), names=nrec.dtype.names)
- assert_equal(mrecfr.a, mrec.a)
- assert_equal(mrecfr.dtype, mrec.dtype)
+ "Test construction from records."
+ (mrec, nrec, ddtype) = self.data
+ #......
+ palist = [(1, 'abc', 3.7000002861022949, 0),
+ (2, 'xy', 6.6999998092651367, 1),
+ (0, ' ', 0.40000000596046448, 0)]
+ pa = recfromrecords(palist, names='c1, c2, c3, c4')
+ mpa = fromrecords(palist, names='c1, c2, c3, c4')
+ assert_equal_records(pa,mpa)
+ #.....
+ _mrec = fromrecords(nrec)
+ assert_equal(_mrec.dtype, mrec.dtype)
+ for field in _mrec.dtype.names:
+ assert_equal(getattr(_mrec, field), getattr(mrec._data, field))
+ #
+ _mrec = fromrecords(nrec.tolist(), names='c1,c2,c3')
+ assert_equal(_mrec.dtype, [('c1',int_),('c2',float_),('c3','|S5')])
+ for (f,n) in zip(('c1','c2','c3'), ('a','b','c')):
+ assert_equal(getattr(_mrec,f), getattr(mrec._data, n))
+ #
+ _mrec = fromrecords(mrec)
+ assert_equal(_mrec.dtype, mrec.dtype)
+ assert_equal_records(_mrec._data, mrec.filled())
+ assert_equal_records(_mrec._fieldmask, mrec._fieldmask)
+
+ def test_fromrecords_wmask(self):
+ "Tests construction from records w/ mask."
+ (mrec, nrec, ddtype) = self.data
+ #
+ _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=[0,1,0,])
+ assert_equal_records(_mrec._data, mrec._data)
+ assert_equal(_mrec._fieldmask.tolist(), [(0,0,0),(1,1,1),(0,0,0)])
+ #
+ _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=True)
+ assert_equal_records(_mrec._data, mrec._data)
+ assert_equal(_mrec._fieldmask.tolist(), [(1,1,1),(1,1,1),(1,1,1)])
+ #
+ _mrec = fromrecords(nrec.tolist(), dtype=ddtype, mask=mrec._fieldmask)
+ assert_equal_records(_mrec._data, mrec._data)
+ assert_equal(_mrec._fieldmask.tolist(), mrec._fieldmask.tolist())
+ #
+ _mrec = fromrecords(nrec.tolist(), dtype=ddtype,
+ mask=mrec._fieldmask.tolist())
+ assert_equal_records(_mrec._data, mrec._data)
+ assert_equal(_mrec._fieldmask.tolist(), mrec._fieldmask.tolist())
def test_fromtextfile(self):
"Tests reading from a text file."
@@ -170,10 +336,11 @@
def test_addfield(self):
"Tests addfield"
- [d, m, mrec] = self.data
- mrec = addfield(mrec, masked_array(d+10, mask=m[::-1]))
- assert_equal(mrec.f2, d+10)
- assert_equal(mrec.f2._mask, m[::-1])
+ (mrec, nrec, ddtype) = self.data
+ (d,m) = ([100,200,300], [1,0,0])
+ mrec = addfield(mrec, masked_array(d, mask=m))
+ assert_equal(mrec.f3, d)
+ assert_equal(mrec.f3._mask, m)
###############################################################################
#------------------------------------------------------------------------------
More information about the Numpy-svn
mailing list