[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