[Scipy-svn] r3383 - in trunk/scipy/sandbox/timeseries: . lib

scipy-svn at scipy.org scipy-svn at scipy.org
Sat Sep 29 15:23:48 EDT 2007


Author: mattknox_ca
Date: 2007-09-29 14:23:41 -0500 (Sat, 29 Sep 2007)
New Revision: 3383

Modified:
   trunk/scipy/sandbox/timeseries/lib/interpolate.py
   trunk/scipy/sandbox/timeseries/lib/moving_funcs.py
   trunk/scipy/sandbox/timeseries/tseries.py
Log:
- removed copy_attributes method (used _update_from from MaskedArray instead)
- minor code and documentation clean up


Modified: trunk/scipy/sandbox/timeseries/lib/interpolate.py
===================================================================
--- trunk/scipy/sandbox/timeseries/lib/interpolate.py	2007-09-29 00:24:52 UTC (rev 3382)
+++ trunk/scipy/sandbox/timeseries/lib/interpolate.py	2007-09-29 19:23:41 UTC (rev 3383)
@@ -10,7 +10,6 @@
 __revision__ = "$Revision$"
 __date__     = '$Date$'
 
-
 import numpy.core.numeric as numeric
 
 from scipy.interpolate import fitpack
@@ -20,14 +19,10 @@
 from maskedarray.extras import flatnotmasked_edges
 marray = MA.array
 
-
 __all__ = [
     'forward_fill', 'backward_fill', 'interp_masked1d',
           ]
 
-
-
-
 #####---------------------------------------------------------------------------
 #---- --- Functions for filling in masked values in a masked array ---
 #####---------------------------------------------------------------------------
@@ -35,8 +30,9 @@
     """forward_fill(marr, maxgap=None)
 
 Forward fills masked values in a 1-d array when there are less maxgap
-consecutive masked values. If maxgap is None, then forward fill all
-masked values."""
+consecutive masked values. If maxgap is None, then forward fill all masked
+values.
+"""
     # Initialization ..................
     if numeric.ndim(marr) > 1:
         raise ValueError,"The input array should be 1D only!"
@@ -63,17 +59,16 @@
                 marr._data[i] = marr._data[i-1]
                 marr._mask[i] = False
     return marr
-#..........................................................
+#.............................................................................
 def backward_fill(marr, maxgap=None):
     """backward_fill(marr, maxgap=None)
 
 Backward fills masked values in a 1-d array when there are less than maxgap
 consecutive masked values. If maxgap is None, then backward fills all
 masked values.
-    """
+"""
     return forward_fill(marr[::-1], maxgap=maxgap)[::-1]
-
-#..........................................................
+#.............................................................................
 def interp_masked1d(marr, kind='linear'):
     """interp_masked1d(marr, king='linear')
 
@@ -112,4 +107,3 @@
                                   (maskedIndices < last_unmasked)]
     marr[interpIndices] = fitpack.splev(interpIndices, tck).astype(marr.dtype)
     return marr
-

Modified: trunk/scipy/sandbox/timeseries/lib/moving_funcs.py
===================================================================
--- trunk/scipy/sandbox/timeseries/lib/moving_funcs.py	2007-09-29 00:24:52 UTC (rev 3382)
+++ trunk/scipy/sandbox/timeseries/lib/moving_funcs.py	2007-09-29 19:23:41 UTC (rev 3383)
@@ -34,12 +34,11 @@
     "process the results from the c function"
 
     rarray = result_dict['array']
-    rtype = result_dict['array'].dtype
     rmask = result_dict['mask']
 
     # makes a copy of the appropriate type
-    data = orig_data.astype(rtype).copy()
-    data.flat = result_dict['array'].ravel()
+    data = orig_data.astype(rarray.dtype).copy()
+    data.flat = rarray.ravel()
     if not hasattr(data, '__setmask__'):
         data = data.view(MA.MaskedArray)
     data.__setmask__(rmask)
@@ -77,7 +76,7 @@
 def mov_sum(data, span, dtype=None):
     """Calculates the moving sum of a series.
 
-:Parameters:
+*Parameters*:
     $$data$$
     $$span$$
     $$dtype$$"""
@@ -91,7 +90,7 @@
 def mov_median(data, span, dtype=None):
     """Calculates the moving median of a series.
 
-:Parameters:
+*Parameters*:
     $$data$$
     $$span$$
     $$dtype$$"""
@@ -105,7 +104,7 @@
 def mov_average(data, span, dtype=None):
     """Calculates the moving average of a series.
 
-:Parameters:
+*Parameters*:
     $$data$$
     $$span$$
     $$dtype$$"""
@@ -131,7 +130,7 @@
 def mov_var(data, span, bias=False, dtype=None):
     """Calculates the moving variance of a 1-D array.
 
-:Parameters:
+*Parameters*:
     $$data$$
     $$span$$
     $$bias$$
@@ -143,7 +142,7 @@
 def mov_stddev(data, span, bias=False, dtype=None):
     """Calculates the moving standard deviation of a 1-D array.
 
-:Parameters:
+*Parameters*:
     $$data$$
     $$span$$
     $$bias$$
@@ -155,7 +154,7 @@
 def mov_covar(x, y, span, bias=False, dtype=None):
     """Calculates the moving covariance of two 1-D arrays.
 
-:Parameters:
+*Parameters*:
     $$x$$
     $$y$$
     $$span$$
@@ -173,7 +172,7 @@
 def mov_corr(x, y, span, dtype=None):
     """Calculates the moving correlation of two 1-D arrays.
 
-:Parameters:
+*Parameters*:
     $$x$$
     $$y$$
     $$span$$
@@ -188,15 +187,16 @@
 def mov_average_expw(data, span, tol=1e-6):
     """Calculates the exponentially weighted moving average of a series.
 
-:Parameters:
+*Parameters*:
     $$data$$
     span : int 
         Time periods. The smoothing factor is 2/(span + 1)
     tol : float, *[1e-6]*
         Tolerance for the definition of the mask. When data contains masked 
-        values, this parameter determinea what points in the result should be masked.
-        Values in the result that would not be "significantly" impacted (as 
-        determined by this parameter) by the masked values are left unmasked."""
+        values, this parameter determinea what points in the result shoud be
+        masked. Values in the result that would not be "significantly"
+        impacted (as determined by this parameter) by the masked values are
+        left unmasked."""
 
     data = marray(data, copy=True, subok=True)
     ismasked = (data._mask is not nomask)
@@ -215,37 +215,38 @@
     data._mask[0] = True
     #
     return data
-#...............................................................................
+#.............................................................................
 def cmov_window(data, span, window_type):
-    """Applies a centered moving window of type window_type and size span on the
-data.
+    """Applies a centered moving window of type window_type and size span on
+the data.
 
 Returns a (subclass of) MaskedArray. The k first and k last data are always 
 masked (with k=span//2). When data has a missing value at position i, the
 result has missing values in the interval [i-k:i+k+1].
     
     
-:Parameters:
-    data : ndarray
-        Data to process. The array should be at most 2D. On 2D arrays, the window
-        is applied recursively on each column.
-    span : integer
+*Parameters*:
+    data : {ndarray}
+        Data to process. The array should be at most 2D. On 2D arrays, the
+        window is applied recursively on each column.
+    span : {int}
         The width of the window.
-    window_type : string/tuple/float
+    window_type : {string/tuple/float}
         Window type (see Notes)
         
-Notes
------
+*Notes*:
 
-The recognized window types are: boxcar, triang, blackman, hamming, hanning, 
-bartlett, parzen, bohman, blackmanharris, nuttall, barthann, kaiser (needs beta), 
-gaussian (needs std), general_gaussian (needs power, width), slepian (needs width).
-If the window requires parameters, the window_type argument should be a tuple
-with the first argument the string name of the window, and the next arguments 
-the needed parameters. If window_type is a floating point number, it is interpreted 
-as the beta parameter of the kaiser window.
+    The recognized window types are: boxcar, triang, blackman, hamming,
+    hanning, bartlett, parzen, bohman, blackmanharris, nuttall, barthann,
+    kaiser (needs beta), gaussian (needs std), general_gaussian (needs power,
+    width), slepian (needs width). If the window requires parameters, the
+    window_type argument should be a tuple with the first argument the string
+    name of the window, and the next arguments the needed parameters. If
+    window_type is a floating point number, it is interpreted as the beta
+    parameter of the kaiser window.
 
-Note also that only boxcar has been thoroughly tested."""
+    Note also that only boxcar has been thoroughly tested.
+"""
 
     data = marray(data, copy=True, subok=True)
     if data._mask is nomask:
@@ -269,57 +270,60 @@
 def cmov_average(data, span):
     """Computes the centered moving average of size span on the data.
     
-    Returns a (subclass of) MaskedArray. The k first and k last data are always 
-    masked (with k=span//2). When data has a missing value at position i, 
-    the result has missing values in the interval [i-k:i+k+1].
-    
-:Parameters:
-    data : ndarray
-        Data to process. The array should be at most 2D. On 2D arrays, the window
-        is applied recursively on each column.
-    span : integer
-        The width of the window."""
+*Parameters*:
+    data : {ndarray}
+        Data to process. The array should be at most 2D. On 2D arrays, the
+        window is applied recursively on each column.
+    span : {int}
+        The width of the window.
+
+*Returns*:    
+    A (subclass of) MaskedArray. The k first and k last data are always masked
+    (with k=span//2). When data has a missing value at position i, the result
+    has missing values in the interval [i-k:i+k+1].
+"""
     return cmov_window(data, span, 'boxcar')
 
 cmov_mean = cmov_average
 
 param_doc = {}
 param_doc['data'] = \
-"""data : ndarray
+"""data : {ndarray}
         Data must be an ndarray (or subclass). In particular, note that
         TimeSeries objects are valid here."""
 
 param_doc['x'] = \
-"""x : ndarray
+"""x : {ndarray}
         First array to be included in the calculation. x must be an ndarray (or
         subclass). In particular, note that TimeSeries objects are valid here."""
 
 param_doc['y'] = \
-"""y : ndarray
+"""y : {ndarray}
         Second array to be included in the calculation. y must be an ndarray (or
         subclass). In particular, note that TimeSeries objects are valid here."""
 
 param_doc['span'] = \
-"""span : int 
+"""span : {int }
         Time periods to use for each calculation."""
 
 param_doc['bias'] = \
-"""bias : boolean (*False*)
+"""bias : {False, True}, optional
         If False, Normalization is by (N-1) where N == span (unbiased
         estimate).  If True then normalization is by N."""
 
 param_doc['dtype'] = \
-"""dtype : numpy data type specification (*None*)
+"""dtype : {numpy data type specification}, optional
         dtype for the result"""
 
 mov_result_doc = \
 """
 
-:Return value:
+*Returns*:
     The result is always a masked array (preserves subclass attributes). The
-    result at index i uses values from [i-span:i+1], and will be masked for the
-    first `span` values. The result will also be masked at i if any of the
-    input values in the slice [i-span:i+1] are masked."""
+    result at index i uses values from [i-span:i+1], and will be masked for
+    the first `span` values. The result will also be masked at i if any of the
+    input values in the slice [i-span:i+1] are masked.
+"""
 
 _g = globals()
 

Modified: trunk/scipy/sandbox/timeseries/tseries.py
===================================================================
--- trunk/scipy/sandbox/timeseries/tseries.py	2007-09-29 00:24:52 UTC (rev 3382)
+++ trunk/scipy/sandbox/timeseries/tseries.py	2007-09-29 19:23:41 UTC (rev 3383)
@@ -19,8 +19,7 @@
 import numpy
 from numpy import ndarray
 from numpy import bool_, complex_, float_, int_, object_
-from numpy.core.multiarray import dtype
-import numpy.core.fromnumeric as fromnumeric
+from numpy import dtype
 import numpy.core.numeric as numeric
 import numpy.core.umath as umath
 from numpy.core.records import recarray
@@ -74,7 +73,7 @@
         marray must be 1 dimensional.
 
 *Returns*:
-    val : {marray.dtype}
+    val : {singleton of type marray.dtype}
         first unmasked value in marray. If all values in marray are masked,
         the function returns the maskedarray.masked constant
 """
@@ -88,7 +87,7 @@
         marray must be 1 dimensional.
 
 *Returns*:
-    val : {marray.dtype}
+    val : {singleton of type marray.dtype}
         last unmasked value in marray. If all values in marray are masked,
         the function returns the maskedarray.masked constant
 """
@@ -156,7 +155,6 @@
                 return False
     return True
 
-
 def _timeseriescompat_multiple(*series):
     """Checks the date compatibility of multiple TimeSeries objects.
     Returns True if everything's fine, or raises an exception. Unlike
@@ -173,26 +171,31 @@
 
     if len(set(start_dates)) > 1:
         errItems = tuple(set(start_dates))
-        raise TimeSeriesCompatibilityError('start_dates', errItems[0], errItems[1])
+        raise TimeSeriesCompatibilityError('start_dates',
+                                           errItems[0], errItems[1])
 
-
     if max(steps) == True:
         bad_index = [x for x, val in enumerate(steps) if val][0]
         raise TimeSeriesCompatibilityError('time_steps',
-                series[0]._dates.get_steps(), series[bad_index]._dates.get_steps())
+                series[0]._dates.get_steps(),
+                series[bad_index]._dates.get_steps())
 
     if len(set(shapes)) > 1:
         errItems = tuple(set(shapes))
-        raise TimeSeriesCompatibilityError('size', "1: %s" % str(errItems[0].shape),
-                                                   "2: %s" % str(errItems[1].shape))
+        raise TimeSeriesCompatibilityError('size',
+                                           "1: %s" % str(errItems[0].shape),
+                                           "2: %s" % str(errItems[1].shape))
 
     return True
 
+def _datadatescompat(data, dates):
+    """Checks the compatibility of dates and data at the creation of a
+TimeSeries.
 
-def _datadatescompat(data, dates):
-    """Checks the compatibility of dates and data at the creation of a TimeSeries.
-    Returns True if everything's fine, raises an exception otherwise."""
-    # If there's only 1 element, the date is a Date object, which has no size...
+Returns True if everything's fine, raises an exception otherwise.
+"""
+    # If there's only 1 element, the date is a Date object, which has no
+    # size...
     tsize = numeric.size(dates)
     dsize = data.size
     # Only one data
@@ -216,14 +219,17 @@
 
 def _compare_frequencies(*series):
     """Compares the frequencies of a sequence of series.
-    Returns the common frequency, or raises an exception if series have different
-    frequencies."""
+
+Returns the common frequency, or raises an exception if series have different
+frequencies.
+"""
     unique_freqs = numpy.unique([x.freqstr for x in series])
     try:
         common_freq = unique_freqs.item()
     except ValueError:
         raise TimeSeriesError, \
-            "All series must have same frequency! (got %s instead)" % unique_freqs
+            "All series must have same frequency! (got %s instead)" % \
+            unique_freqs
     return common_freq
 
 ##### ------------------------------------------------------------------------
@@ -231,10 +237,10 @@
 ##### ------------------------------------------------------------------------
 class _tsmathmethod(object):
     """Defines a wrapper for arithmetic array methods (add, mul...).
-When called, returns a new TimeSeries object, with the new series the result of
-the method applied on the original series.
-The `_dates` part remains unchanged.
-    """
+When called, returns a new TimeSeries object, with the new series the result
+of the method applied on the original series. The `_dates` part remains
+unchanged.
+"""
     def __init__ (self, methodname):
         self._name = methodname
 
@@ -287,11 +293,11 @@
             result._dates = getattr(instance._dates, _name)(*args)
         else:
             result._dates = instance._dates
-        result.copy_attributes(instance)
         return result
 
 class _tsaxismethod(object):
     """Defines a wrapper for array methods working on an axis (mean...).
+
 When called, returns a ndarray, as the result of the method applied on the
 series.
 """
@@ -347,7 +353,6 @@
     it is typically recommended to use the `time_series` function for
     construction as it allows greater flexibility and convenience.
 """
-    _genattributes = ['fill_value']
     def __new__(cls, data, dates, mask=nomask, dtype=None, copy=False,
                 fill_value=None, subok=True, keep_mask=True, small_mask=True,
                 hard_mask=False, **options):
@@ -405,7 +410,8 @@
         if isinstance(indx, int):
             return (indx, indx)
         elif isinstance(indx, str):
-            indx = self._dates.date_to_index(Date(self._dates.freq, string=indx))
+            indx = self._dates.date_to_index(
+                                    Date(self._dates.freq, string=indx))
             return (indx, indx)
         elif isDate(indx):
             indx = self._dates.date_to_index(indx)
@@ -432,7 +438,8 @@
         elif isTimeSeries(indx):
             indx = indx._series
         if getmask(indx) is not nomask:
-            msg = "Masked arrays must be filled before they can be used as indices!"
+            msg = "Masked arrays must be filled before they can be used " + \
+                  "as indices!"
             raise IndexError, msg
         return (indx,indx)
 
@@ -680,8 +687,9 @@
     relation : {'AFTER', 'BEFORE'} , optional
 
 *Returns*:
-    a new TimeSeries (data copied) with the .dates DateArray at the specified
-    frequency (the .asfreq method of the .dates property will be called)
+    a new TimeSeries with the .dates DateArray at the specified frequency (the
+    .asfreq method of the .dates property will be called). The data in the
+    resulting series will be a VIEW of the original series.
 
 *Notes*:
     The parameters are the exact same as for DateArray.asfreq , please see the
@@ -691,18 +699,23 @@
         if freq is None: return self
 
         return TimeSeries(self._series,
-                          dates=self._dates.asfreq(freq, relation=relation),
-                          copy=True)
+                          dates=self._dates.asfreq(freq, relation=relation))
     #.....................................................
     def transpose(self, *axes):
-        """ a.transpose(*axes)
+        """Returns a view of the series with axes transposed
 
-    Returns a view of 'a' with axes transposed. If no axes are given,
-    or None is passed, switches the order of the axes. For a 2-d
-    array, this is the usual matrix transpose. If axes are given,
-    they describe how the axes are permuted.
+*Parameters*:
+    *axes : {integers}
+        the axes to swap
 
-        """
+*Returns*:
+    a VIEW of the series with axes for both the data and dates transposed
+
+*Notes*:
+    If no axes are given, the order of the axes are switches. For a 2-d array,
+    this is the usual matrix transpose. If axes are given, they describe how
+    the axes are permuted.
+"""
         if self._dates.size == self.size:
             result = super(TimeSeries, self).transpose(*axes)
             result._dates = self._dates.transpose(*axes)
@@ -716,7 +729,7 @@
         return result
     
     def split(self):
-        """Split a multiple series into individual columns."""
+        """Split a multi-dimensional series into individual columns."""
         if self.ndim == 1:
             return [self]
         else:
@@ -727,28 +740,18 @@
                                    **_attrib_dict(self)) for a in arr]        
     
     def filled(self, fill_value=None):
-        """Returns an array of the same class as `_data`,
- with masked values filled with `fill_value`.
-Subclassing is preserved.
+        """Returns an array of the same class as `_data`,  with masked values
+filled with `fill_value`. Subclassing is preserved.
 
-If `fill_value` is None, uses self.fill_value.
-        """
+*Parameters*:
+    fill_value : {None, singleton of type self.dtype}, optional
+        The value to fill in masked values with. If `fill_value` is None, uses
+        self.fill_value.
+"""
         result = self._series.filled(fill_value=fill_value).view(type(self))
         result._dates = self._dates
-        result.copy_attributes(self)
         return result
-    
     #......................................................
-    def copy_attributes(self, oldseries, exclude=[]):
-        "Copies the attributes from oldseries if they are not in the exclude list."
-        attrlist = type(self)._genattributes
-        if not isinstance(oldseries, TimeSeries):
-            msg = "Series should be a valid TimeSeries object! (got <%s> instead)"
-            raise TimeSeriesError, msg % type(oldseries)
-        for attr in attrlist:
-            if not attr in exclude:
-                setattr(self, attr, getattr(oldseries, attr))
-    #......................................................
     # Pickling
     def __getstate__(self):
         "Returns the internal state of the TimeSeries, for pickling purposes."
@@ -855,7 +858,7 @@
             if hasattr(method, '__call__'):
                 return method.__call__(*args, **params)
             return method
-        method = getattr(fromnumeric.asarray(caller), self._methodname)
+        method = getattr(numpy.asarray(caller), self._methodname)
         try:
             return method(*args, **params)
         except SystemError:
@@ -1168,7 +1171,7 @@
         start_date = max(start_date, dstart)
         end_date = min(end_date, dend) + 1
         newseries[start_date:end_date] = a[start_date:end_date]
-    newseries.copy_attributes(a)
+    newseries._update_from(a)
     return newseries
 #.....................................................
 def align_series(*series, **kwargs):
@@ -1270,7 +1273,7 @@
     newseries = tempData.view(type(series))
     newseries._dates = date_array(start_date=start_date, length=len(newseries),
                                   freq=toFreq)
-    newseries.copy_attributes(series)
+    newseries._update_from(series)
     return newseries
 
 def convert(series, freq, func=None, position='END', *args, **kwargs):
@@ -1362,7 +1365,7 @@
         newdata = inidata
     newseries = newdata.view(type(series))
     newseries._dates = series._dates
-    newseries.copy_attributes(series)
+    newseries._update_from(series)
     return newseries
 TimeSeries.tshift = tshift
 #...............................................................................
@@ -1392,7 +1395,7 @@
         newdata[nper:] = 100*(series._series[nper:]/series._series[:-nper] - 1)
     newseries = newdata.view(type(series))
     newseries._dates = series._dates
-    newseries.copy_attributes(series)
+    newseries._update_from(series)
     return newseries
 TimeSeries.pct = pct
 #...............................................................................




More information about the Scipy-svn mailing list