[Scipy-svn] r2523 - in trunk/Lib/sandbox/maskedarray: . tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Wed Jan 10 12:48:42 EST 2007
Author: pierregm
Date: 2007-01-10 11:48:37 -0600 (Wed, 10 Jan 2007)
New Revision: 2523
Added:
trunk/Lib/sandbox/maskedarray/mrecords.py
trunk/Lib/sandbox/maskedarray/tests/test_mrecarray.py
Modified:
trunk/Lib/sandbox/maskedarray/CHANGELOG
Log:
cf changelog
Modified: trunk/Lib/sandbox/maskedarray/CHANGELOG
===================================================================
--- trunk/Lib/sandbox/maskedarray/CHANGELOG 2007-01-10 15:42:24 UTC (rev 2522)
+++ trunk/Lib/sandbox/maskedarray/CHANGELOG 2007-01-10 17:48:37 UTC (rev 2523)
@@ -1,3 +1,11 @@
+#2007-01-10 : Mrecords
+# : - Defines a class of records that support masked arrays
+#2007-01-08 : Core:
+# : - Forced to reset the class defaults after initialization
+# : - Forced the MaskedArray class defaults to be reset
+# : - Modified __array_finallize__ to allow objects w/ _data and _mask fields to be recognized as MA
+#2007-01-04 : Core:
+# : - Fixed a but in masked_all_like
#2007-01-02 : Extras
# : - Made sure that apply_along_axis output the proper fill_value
# : Core
Property changes on: trunk/Lib/sandbox/maskedarray/CHANGELOG
___________________________________________________________________
Name: svn:keywords
+ Date
Author
Revision
Id
Added: trunk/Lib/sandbox/maskedarray/mrecords.py
===================================================================
--- trunk/Lib/sandbox/maskedarray/mrecords.py 2007-01-10 15:42:24 UTC (rev 2522)
+++ trunk/Lib/sandbox/maskedarray/mrecords.py 2007-01-10 17:48:37 UTC (rev 2523)
@@ -0,0 +1,633 @@
+"""mrecords
+Defines a class of record arrays supporting masked arrays.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id$
+"""
+__author__ = "Pierre GF Gerard-Marchant ($Author$)"
+__version__ = '1.0'
+__revision__ = "$Revision$"
+__date__ = '$Date$'
+
+import sys
+import types
+
+import numpy as N
+from numpy import bool_, complex_, float_, int_, str_, object_
+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 import bool_
+
+from numpy.core.records import format_parser, record, recarray
+
+ndarray = numeric.ndarray
+_byteorderconv = N.core.records._byteorderconv
+_typestr = ntypes._typestr
+
+import maskedarray as MA
+reload(MA)
+filled = MA.filled
+getmaskarray = MA.getmaskarray
+masked = MA.masked
+nomask = MA.nomask
+mask_or = MA.mask_or
+masked_array = MA.masked_array
+
+import warnings
+import logging
+logging.basicConfig(level=logging.DEBUG,
+ format='%(name)-15s %(levelname)s %(message)s',)
+
+
+class mrecarray(ndarray):
+ """
+
+:IVariables:
+ - `__localfdict` : Dictionary
+ Dictionary of local fields (`f0_data`, `f0_mask`...)
+ - `__globalfdict` : Dictionary
+ Dictionary of global fields, as the combination of a `_data` and a `_mask`.
+ (`f0`)
+ """
+ __localfdict = {}
+ __globalfdict = {}
+ def __new__(subtype, shape, dtype=None, buf=None, offset=0, strides=None,
+ formats=None, names=None, titles=None,
+ byteorder=None, aligned=False, hard_mask=False):
+
+ if dtype is not None:
+ descr = numeric.dtype(dtype)
+ else:
+ descr = format_parser(formats, names, titles, aligned, byteorder)._descr
+
+ if buf is None:
+ mrec = ndarray.__new__(subtype, shape, (record, descr))
+ else:
+ mrec = ndarray.__new__(subtype, shape, (record, descr),
+ buffer=buf, offset=offset,
+ strides=strides)
+ # Stores the field names in directories..
+ mrec.__localfdict = dict(descr.fields)
+ mrec.__globalfdict = {}
+ keys = sorted(mrec.__localfdict.keys())
+ for i in range(len(keys)//2):
+ ikey = keys[2*i]
+ nkey = "_".join(ikey.split('_')[:-1])
+ (dfield, mfield) = ("%s_data" % nkey, "%s_mask" % nkey)
+ mrec.__globalfdict[nkey] = dict(_data=mrec.__localfdict[dfield],
+ _mask=mrec.__localfdict[mfield])
+ mrec._hardmask = hard_mask
+ return mrec
+
+ def __getallfields(self,fieldname):
+ """Returns all the fields sharing the same fieldname base.
+ The fieldname base is either `_data` or `_mask`."""
+ logging.debug('__getallfields(%s)' % fieldname)
+ (names, formats, offsets, objs) = ([], [], [], [])
+ fkeyname = '%%s%s' % fieldname
+ for s in self._mrecarray__globalfdict.keys():
+ fkey = fkeyname % s
+ fattr = self._mrecarray__localfdict[fkey]
+ names.append(s)
+ obj = self.__getobj(ndarray.__getitem__(self,fkey))
+ objs.append(obj)
+ formats.append(fattr[0])
+ offsets.append(fattr[1])
+ descr = [(n,f) for (n,f) in zip(names, formats)]
+ return N.core.records.fromarrays(objs, dtype=descr)
+
+ def _getdata(self):
+ """Returns all the `_data` fields."""
+ return self.__getallfields('_data')
+
+ def _getfieldmask(self):
+ """Returns a recarray of the mask of each field."""
+ return self.__getallfields('_mask')
+
+ def _getmask(self):
+ """Returns the mask of the mrecarray.
+ An element of the mrecarray is considered masked when all the corresponding
+ fields are masked."""
+ nbfields = len(self.dtype )//2
+ recmask = self._getfieldmask().view(bool_).reshape(-1,nbfields)
+ return recmask.all(1)
+
+ def __getobj(self, obj, viewtype=ndarray):
+ "Returns an object as a view of a ndarray, or as itself."
+ if (isinstance(obj, ndarray) and obj.dtype.isbuiltin):
+ return obj.view(viewtype)
+ return obj
+ #......................................................
+ def __getattribute__(self, attr):
+ try:
+ # Returns a generic attribute
+ return object.__getattribute__(self,attr)
+ except AttributeError:
+ # OK, so attr must be a field name
+ pass
+ # Get the list of fields ......
+ fdict = ndarray.__getattribute__(self,'_mrecarray__localfdict') or {}
+ # Case #1: attr is a basic field
+ if attr in fdict.keys():
+ fattr = fdict[attr]
+ obj = self.getfield(*fattr)
+ if obj.dtype.fields:
+ return obj
+ if obj.dtype.char in 'SU':
+ return obj.view(chararray)
+ return obj.view(ndarray)
+ # Case #2: attr is acompund field
+ elif ("%s_data" % attr) in fdict.keys():
+ data = self.getfield(*fdict["%s_data" % attr ][:2])
+ mask = self.getfield(*fdict["%s_mask" % attr ][:2])
+ return MA.masked_array(data.view(ndarray),
+ mask=mask.view(ndarray),
+ copy=False)
+ # Case #3/4/5: attr is a generic field
+ elif attr == '_data':
+ func = ndarray.__getattribute__(self,'_mrecarray__getallfields')
+ return func.__call__('_data')
+ elif attr == '_fieldmask':
+ func = ndarray.__getattribute__(self,'_mrecarray__getallfields')
+ return func.__call__('_mask')
+ elif attr == '_mask':
+ logging.debug('__getattribute__: all fields %s' % attr)
+ func = ndarray.__getattribute__(self,'_getmask')
+ return func.__call__()
+ # Case #6: attr is not a field at all !
+ else:
+ raise AttributeError, "record array has no attribute %s" % attr
+
+# Save the dictionary
+# If the attr is a field name and not in the saved dictionary
+# Undo any "setting" of the attribute and do a setfield
+# Thus, you can't create attributes on-the-fly that are field names.
+
+ def __setattr__(self, attr, val):
+ # gets some status on attr: an existing field ? a new attribute ?
+ fdict = ndarray.__getattribute__(self,'_mrecarray__localfdict') or {}
+ gdict = ndarray.__getattribute__(self,'_mrecarray__globalfdict') or {}
+ attrlist = fdict.keys() + ['_data', '_fieldmask', '_mask']
+ isvalidattr = (attr in attrlist ) or ('%s_data' % attr in attrlist)
+ newattr = attr not in self.__dict__
+
+ 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
+ if not isvalidattr:
+ exctype, value = sys.exc_info()[:2]
+ raise exctype, value
+ else:
+ if not isvalidattr:
+ return ret
+ 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 ............
+ if attr in fdict.keys():
+ return self.setfield(val, *fdict[attr][:2])
+ # Case #2 Compund field ............
+ elif ("%s_data" % attr) in fdict.keys():
+ data = self.setfield(filled(val), *fdict["%s_data" % attr ][:2])
+ mask = self.setfield(getmaskarray(val), *fdict["%s_mask" % attr ][:2])
+ return
+ elif attr == '_data':
+ fval = filled(val)
+ for k in gdict.keys():
+ self.setfield(fval, *gdict["%s_data" % k ][:2])
+ return
+# func = ndarray.__getattribute__(self,'_mrecarray__getallfields')
+# return func.__call__('_data')
+ elif attr == '_fieldmask':
+ mval = getmaskarray(val)
+ for k in gdict.keys():
+ self.setfield(mval, *gdict["%s_mask" % k ][:2])
+ return
+# func = ndarray.__getattribute__(self,'_mrecarray__getallfields')
+# return func.__call__('_mask')
+ elif attr == '_mask':
+ logging.debug(" setattr _mask to %s [%s]" % (val,(val is nomask)))
+ if self._hardmask:
+ logging.debug("setattr: object has hardmask")
+ if val is not nomask:
+ mval = getmaskarray(val)
+ for k in gdict.keys():
+ fkey = fdict["%s_mask" % k ][:2]
+ m = mask_or(mval, self.getfield(*fkey))
+ logging.debug("setattr: set %s to %s" % (k,m))
+ self.setfield(m, *fkey)
+ else:
+ mval = getmaskarray(val)
+ for k in gdict.keys():
+ self.setfield(mval, *fdict["%s_mask" % k ][:2])
+ logging.debug('__getattribute__: all fields %s' % attr)
+ return
+# func = ndarray.__getattribute__(self,'_getmask')
+# return func.__call__()
+
+
+ #......................................................
+ def __getitem__(self, indx):
+ logging.debug('__getitem__ got %s' % indx)
+ try:
+ obj = ndarray.__getitem__(self, indx)
+ except ValueError:
+ if indx in self.__globalfdict.keys():
+ objd = ndarray.__getitem__(self, "%s_data" % indx)
+ objm = ndarray.__getitem__(self, "%s_mask" % indx)
+ return MA.masked_array(objd.view(ndarray),
+ mask=objm.view(ndarray))
+ elif indx in ['_data', '_fieldmask']:
+ return self.__getallfields(indx)
+ elif indx == '_mask':
+ return self._getmask()
+ else:
+ msg = "Cannot do anything w/ indx '%s'!" % indx
+ raise ValueError, msg
+
+# logging.debug('__getitem__ send %s' % type(self.__getobj(obj)))
+ return self.__getobj(obj)
+ #.......................................................
+ def field(self,attr, val=None):
+ """Sets the field `attr` to the new value `val`.
+ If `val` is None, returns the corresponding field.
+ """
+ if isinstance(attr,int):
+ names = ndarray.__getattribute__(self,'dtype').names
+ attr = names[attr]
+
+ fdict = ndarray.__getattribute__(self,'_mrecarray__localfdict') or {}
+ f = fdict[attr]
+ # Case #1: just retrieve the data .......
+ if val is None:
+ try:
+ return self.__getattribute__(attr)
+ except:
+ raise ValueError, "Unable to retrieve field '%s'" % attr
+ # Case #2: set the field to a new value ..
+ else:
+ try:
+ return self.__setattribute__(attr)
+ except:
+ raise ValueError, "Unable to set field '%s'" % attr
+ #......................................................
+ def view(self, obj):
+ """Returns a view of the mrecarray."""
+ try:
+ if issubclass(obj, ndarray):
+ logging.debug('direct view as %s' % obj)
+ return ndarray.view(self, obj)
+ except TypeError:
+ pass
+ dtype = numeric.dtype(obj)
+ if dtype.fields is None:
+ return self.__array__().view(dtype)
+ return ndarray.view(self, obj)
+ #............................................
+ def harden_mask(self):
+ "Forces the mask to hard"
+ self._hardmask = True
+ def soften_mask(self):
+ "Forces the mask to soft"
+ self._hardmask = False
+
+#####---------------------------------------------------------------------------
+#---- --- Constructors ---
+#####---------------------------------------------------------------------------
+def _splitfields(descr):
+ """Creates a new descriptor from the descriptor `descr`.
+ The initial fields are renamed by adding a `_data` suffix to the name.
+ Their dtype is kept.
+ New fields are also created from the initial ones by adding a `_mask` suffix
+ to the name.
+ The dtype of these latter is set to `bool_`
+ """
+ mdescr = []
+ for (n,d) in descr.descr:
+ mdescr.append( ("%s_data" % n, d) )
+ mdescr.append( ("%s_mask" % n, bool_) )
+ return numeric.dtype(mdescr)
+
+def fromarrays(arraylist, dtype=None, shape=None, formats=None,
+ names=None, titles=None, aligned=False, byteorder=None):
+ """Creates a mrecarray from a (flat) list of masked arrays.
+
+: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
+ Data type descriptor.
+ - `shape` : Integer *[None]*
+ Number of records. If None, `shape` is defined from the shape of the first
+ array in the list.
+ - `formats` :
+ (Description to write)
+ - `names` :
+ (description to write)
+ - `titles`:
+ (Description to write)
+ - `aligned`: Boolen *[False]*
+ (Description to write, not used anyway)
+ - `byteorder`: Boolen *[None]*
+ (Description to write, not used anyway)
+
+
+ """
+ arraylist = [MA.asarray(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:
+ # go through each object in the list to see if it is an ndarray
+ # and determine the formats.
+ formats = ''
+ for obj in arraylist:
+ if not isinstance(obj, ndarray):
+ raise ValueError, "item in the array list must be an ndarray."
+ formats += _typestr[obj.dtype.type]
+ if issubclass(obj.dtype.type, ntypes.flexible):
+ formats += `obj.itemsize`
+ formats += ','
+ formats = formats[:-1]
+
+ logging.debug("fromarrays: formats",formats)
+ # 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
+ mdescr = _splitfields(descr)
+ _array = mrecarray(shape, mdescr)
+ _names = mdescr.names
+ # Populate the record array (makes a copy)
+ for i in range(len(arraylist)):
+ logging.debug("fromarrays: i:%i-%s/%s" % \
+ (i, arraylist[i]._data, MA.getmaskarray(arraylist[i])))
+ logging.debug("fromarrays: i:%i-%s/%s" % \
+ (i,_names[2*i], _names[2*i+1]))
+ _array[_names[2*i]] = arraylist[i]._data
+ _array[_names[2*i+1]] = getmaskarray(arraylist[i])
+ return _array
+#..............................................................................
+def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None,
+ titles=None, aligned=False, byteorder=None):
+ """Creates a mrecarray from a list of records.
+
+ The data in the same field can be heterogeneous, they will be promoted
+ to the highest data type. This method is intended for creating
+ smaller record arrays. If used to create large array without formats
+ defined
+
+ r=fromrecords([(2,3.,'abc')]*100000)
+
+ it can be slow.
+
+ If formats is None, then this will auto-detect formats. Use list of
+ tuples rather than list of lists for faster processing.
+
+ >>> r=fromrecords([(456,'dbe',1.2),(2,'de',1.3)],names='col1,col2,col3')
+ >>> print r[0]
+ (456, 'dbe', 1.2)
+ >>> r.col1
+ array([456, 2])
+ >>> r.col2
+ chararray(['dbe', 'de'])
+ >>> import cPickle
+ >>> print cPickle.loads(cPickle.dumps(r))
+ recarray[
+ (456, 'dbe', 1.2),
+ (2, 'de', 1.3)
+ ]
+ """
+ # Case #1: reclist is in fact a mrecarray ........
+ if isinstance(reclist, mrecarray):
+ mdescr = reclist.dtype
+ shape = reclist.shape
+ _array = mrecarray(shape, mdescr)
+ for (i,r) in enumerate(reclist):
+ _array[i] = r
+ return _array
+
+ # No format, no dtype: create from to arrays .....
+ 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 = nrec.dtype.names
+ else:
+ obj = numeric.array(reclist,dtype=object)
+ arrlist = [numeric.array(obj[...,i].tolist())
+ for i in xrange(nfields)]
+ return fromarrays(arrlist, formats=formats, shape=shape, 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
+ mdescr = _splitfields(descr)
+
+ try:
+ retval = numeric.array(reclist, dtype = descr)
+ 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."
+ _array = recarray(shape, mdescr)
+ raise NotImplementedError,"I should really test that..."
+ for k in xrange(_array.size):
+ _array[k] = tuple(reclist[k])
+ return _array
+ else:
+ if shape is not None and retval.shape != shape:
+ retval.shape = shape
+ #
+ tmp = retval.view(recarray)
+ _array = mrecarray(shape, mdescr)
+ for n in tmp.dtype.names:
+ _array['%s_data' % n] = tmp[n]
+ _array['%s_mask' % n] = nomask
+ return _array
+
+def _guessvartypes(arr):
+ """Tries to guess the dtypes of the str_ ndarray `arr`, by testing element-wise
+ conversion. Returns a list of dtypes.
+ The array is first converted to ndarray. If the array is 2D, the test is
+ performed on the first line. An exception is raised if the file is 3D or more.
+ """
+ vartypes = []
+ arr = numeric.asarray(arr)
+ if len(arr.shape) == 2 :
+ arr = arr[0]
+ elif len(arr.shape) > 2:
+ raise ValueError, "The array should be 2D at most!"
+ # Start the conversion loop .......
+ for f in arr:
+ try:
+ val = int(f)
+ except ValueError:
+ try:
+ val = float(f)
+ except ValueError:
+ try:
+ val = complex(f)
+ except ValueError:
+ print "str_!"
+ vartypes.append(arr.dtype)
+ else:
+ vartypes.append(complex_)
+ else:
+ vartypes.append(float_)
+ else:
+ vartypes.append(int_)
+ return vartypes
+
+def openfile(fname):
+ "Opens the file handle of file `fname`"
+ # A file handle ...................
+ if hasattr(fname, 'readline'):
+ return fname
+ # Try to open the file and guess its type
+ try:
+ f = open(fname)
+ except IOError:
+ raise IOError, "No such file: '%s'" % fname
+ if f.readline()[:2] != "\\x":
+ f.seek(0,0)
+ return f
+ raise NotImplementedError, "Wow, binary file"
+
+
+def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='',
+ varnames=None, vartypes=None):
+ """Creates a mrecarray from data stored in the file `filename`.
+
+:Parameters:
+ - `filename` : file name/handle
+ Handle of an opened file.
+ - `delimitor` : Character *None*
+ Alphanumeric character used to separate columns in the file.
+ If None, any (group of) white spacestring(s) will be used.
+ - `commentchar` : String *['#']*
+ Alphanumeric character used to mark the start of a comment.
+ - `missingchar` : String *['']*
+ String indicating missing data, and used to create the masks.
+ - `varnames` : Sequence *[None]*
+ Sequence of the variable names. If None, a list will be created from
+ the first non empty line of the file.
+ - `vartypes` : Sequence *[None]*
+ Sequence of the variables dtypes. If None, the sequence will be estimated
+ from the first non-commented line.
+
+
+ Ultra simple: the varnames are in the header, one line"""
+ # Try to open the file ......................
+ f = openfile(fname)
+ # Get the first non-empty line as the varnames
+ while True:
+ line = f.readline()
+ firstline = line[:line.find(commentchar)].strip()
+ _varnames = firstline.split(delimitor)
+ print "_VARNAMES:%s-"%_varnames, len(_varnames)
+ if len(_varnames) > 1:
+ break
+ if varnames is None:
+ varnames = _varnames
+ # Get the data ..............................
+ _variables = [line.strip().split(delimitor) for line in f
+ if line[0] != commentchar and len(line) > 1]
+ _variables = N.array(_variables)
+ #_variables = MA.masked_equal(_variables,'')
+ (nvars, nfields) = _variables.shape
+ # Try to guess the dtype ....................
+ if vartypes is None:
+ vartypes = _guessvartypes(_variables[0])
+ else:
+ vartypes = [numeric.dtype(v) for v in vartypes]
+ if len(vartypes) != nfields:
+ msg = "Attempting to %i dtypes for %i fields!"
+ msg += " Reverting to default."
+ warnings.warn(msg % (len(vartypes), nfields))
+ vartypes = _guessvartypes(_variables[0])
+ # Construct the descriptor ..................
+ mdescr = [(n,f) for (n,f) in zip(varnames, vartypes)]
+ # Get the data and the mask .................
+ # We just need a list of masked_arrays. It's easier to create it like that:
+ _mask = (_variables.T == '')
+ _datalist = [masked_array(a,mask=m,dtype=t)
+ for (a,m,t) in zip(_variables.T, _mask, vartypes)]
+ return fromarrays(_datalist, dtype=mdescr)
+
+
+
+################################################################################
+from maskedarray.testutils import assert_equal, assert_array_equal
+if 1:
+ if 0:
+ fcontent = """#
+'One (S)','Two (I)','Three (F)','Four (M)','Five (-)','Six (C)'
+'strings',1,1.0,'mixed column',,1
+'with embedded "double quotes"',2,2.0,1.0,,1
+'strings',3,3.0E5,3,,1
+'strings',4,-1e-10,,,1
+"""
+ import os
+ from datetime import datetime
+ fname = 'tmp%s' % datetime.now().strftime("%y%m%d%H%M%S%s")
+ f = open(fname, 'w')
+ f.write(fcontent)
+ f.close()
+ mrectxt = fromtextfile(fname,delimitor=',',varnames='ABCDEFG')
+ os.unlink(fname)
+ #
+ assert(isinstance(mrectxt, mrecarray))
+ assert_equal(mrectxt.F, [1,1,1,1])
+ assert_equal(mrectxt.E._mask, [1,1,1,1])
+ assert_equal(mrectxt.C, [1,2,3.e+5,-1e-10])
+#...............................................................................
+
+
+
+
+
+
Property changes on: trunk/Lib/sandbox/maskedarray/mrecords.py
___________________________________________________________________
Name: svn:keywords
+ Date
Author
Revision
Id
Added: trunk/Lib/sandbox/maskedarray/tests/test_mrecarray.py
===================================================================
--- trunk/Lib/sandbox/maskedarray/tests/test_mrecarray.py 2007-01-10 15:42:24 UTC (rev 2522)
+++ trunk/Lib/sandbox/maskedarray/tests/test_mrecarray.py 2007-01-10 17:48:37 UTC (rev 2523)
@@ -0,0 +1,131 @@
+# pylint: disable-msg=W0611, W0612, W0511,R0201
+"""Tests suite for mrecarray.
+
+:author: Pierre Gerard-Marchant
+:contact: pierregm_at_uga_dot_edu
+:version: $Id$
+"""
+__author__ = "Pierre GF Gerard-Marchant ($Author$)"
+__version__ = '1.0'
+__revision__ = "$Revision$"
+__date__ = '$Date$'
+
+import types
+
+import numpy as N
+import numpy.core.fromnumeric as fromnumeric
+from numpy.testing import NumpyTest, NumpyTestCase
+from numpy.testing.utils import build_err_msg
+
+import maskedarray.testutils
+reload(maskedarray.testutils)
+from maskedarray.testutils import *
+
+import maskedarray.core as MA
+#reload(MA)
+import maskedarray.mrecords
+#reload(maskedarray.mrecords)
+from maskedarray.mrecords import mrecarray, fromarrays, fromtextfile, fromrecords
+
+
+#..............................................................................
+class test_mrecarray(NumpyTestCase):
+ "Base test class for MaskedArrays."
+ def __init__(self, *args, **kwds):
+ NumpyTestCase.__init__(self, *args, **kwds)
+ self.setup()
+
+ def setup(self):
+ "Generic setup"
+ d = N.arange(5)
+ m = 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 = MA.array(base_d, mask=base_m)
+ mrec = fromarrays(base.T,)
+ self.data = [d, m, mrec]
+
+ def test_get(self):
+ "Tests fields retrieval"
+ [d, m, mrec] = self.data
+ assert_equal(mrec.f0, MA.array(d,mask=m))
+ assert_equal(mrec.f1, MA.array(d[::-1],mask=m[::-1]))
+ assert((mrec._fieldmask == N.core.records.fromarrays([m, m[::-1]])).all())
+ assert_equal(mrec._mask, N.r_[[m,m[::-1]]].all(0))
+ assert_equal(mrec.f0, mrec['f0'])
+
+ def test_set(self):
+ "Tests setting fields/attributes."
+ [d, m, mrec] = self.data
+ mrec.f0_data = 5
+ assert_equal(mrec['f0_data'], [5,5,5,5,5])
+ mrec.f0 = 1
+ assert_equal(mrec['f0_data'], [1]*5)
+ assert_equal(mrec['f0_mask'], [0]*5)
+ mrec.f1 = MA.masked
+ assert_equal(mrec.f1.mask, [1]*5)
+ assert_equal(mrec['f1_mask'], [1]*5)
+ mrec._mask = MA.masked
+ assert_equal(mrec['f1_mask'], [1]*5)
+ assert_equal(mrec['f0_mask'],mrec['f1_mask'])
+ mrec._mask = MA.nomask
+ assert_equal(mrec['f1_mask'], [0]*5)
+ assert_equal(mrec['f0_mask'],mrec['f1_mask'])
+
+ def test_hardmask(self):
+ "Test hardmask"
+ [d, m, mrec] = self.data
+ print mrec._mask
+ 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_equal(mrec['f1_mask'], [0]*5)
+ assert_equal(mrec['f0_mask'],mrec['f1_mask'])
+
+ def test_fromtextfile(self):
+ "Tests reading from a text file."
+ fcontent = """#
+'One (S)','Two (I)','Three (F)','Four (M)','Five (-)','Six (C)'
+'strings',1,1.0,'mixed column',,1
+'with embedded "double quotes"',2,2.0,1.0,,1
+'strings',3,3.0E5,3,,1
+'strings',4,-1e-10,,,1
+"""
+ import os
+ from datetime import datetime
+ fname = 'tmp%s' % datetime.now().strftime("%y%m%d%H%M%S%s")
+ f = open(fname, 'w')
+ f.write(fcontent)
+ f.close()
+ mrectxt = fromtextfile(fname,delimitor=',',varnames='ABCDEFG')
+ os.unlink(fname)
+ #
+ assert(isinstance(mrectxt, mrecarray))
+ assert_equal(mrectxt.F, [1,1,1,1])
+ assert_equal(mrectxt.E._mask, [1,1,1,1])
+ assert_equal(mrectxt.C, [1,2,3.e+5,-1e-10])
+
+ def test_fromrecords(self):
+ "Test from recarray."
+ [d, m, mrec] = self.data
+ nrec = N.core.records.fromarrays(N.r_[[d,d[::-1]]])
+ mrecfr = fromrecords(nrec.tolist())
+ assert_equal(mrecfr.f0, mrec.f0)
+ assert_equal(mrecfr.dtype, mrec.dtype)
+ #....................
+ mrecfr = fromrecords(nrec)
+ assert_equal(mrecfr.f0, mrec.f0)
+ assert_equal(mrecfr.dtype, mrec.dtype)
+ #....................
+ tmp = mrec[::-1] #.tolist()
+ mrecfr = fromrecords(tmp)
+ assert_equal(mrecfr.f0, mrec.f0[::-1])
+
+###############################################################################
+#------------------------------------------------------------------------------
+if __name__ == "__main__":
+ NumpyTest().run()
\ No newline at end of file
Property changes on: trunk/Lib/sandbox/maskedarray/tests/test_mrecarray.py
___________________________________________________________________
Name: svn:keywords
+ Date
Author
Revision
Id
More information about the Scipy-svn
mailing list