[Scipy-svn] r2726 - in trunk/Lib/sandbox/timeseries: . tests
scipy-svn at scipy.org
scipy-svn at scipy.org
Mon Feb 19 02:37:45 EST 2007
Author: pierregm
Date: 2007-02-19 01:37:26 -0600 (Mon, 19 Feb 2007)
New Revision: 2726
Modified:
trunk/Lib/sandbox/timeseries/tdates.py
trunk/Lib/sandbox/timeseries/tests/test_dates.py
trunk/Lib/sandbox/timeseries/tests/test_timeseries.py
trunk/Lib/sandbox/timeseries/tseries.py
Log:
tdates : ensures compatibility w/ new MaskedArray + misc cleanup
tseries : ensures compatibility w/ new MaskedArray + misc cleanup
Modified: trunk/Lib/sandbox/timeseries/tdates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tdates.py 2007-02-19 06:52:16 UTC (rev 2725)
+++ trunk/Lib/sandbox/timeseries/tdates.py 2007-02-19 07:37:26 UTC (rev 2726)
@@ -21,6 +21,8 @@
from numpy import ndarray
import numpy.core.numeric as numeric
import numpy.core.fromnumeric as fromnumeric
+import numpy.core.numerictypes as ntypes
+from numpy.core.numerictypes import generic
import maskedarray as MA
#reload(MA)
@@ -225,47 +227,48 @@
@property
def day(self):
"Returns the day of month."
- return self.__getDateInfo('D')
+ return self.__getdateinfo__('D')
@property
def day_of_week(self):
"Returns the day of week."
- return self.__getDateInfo('W')
+ return self.__getdateinfo__('W')
@property
def day_of_year(self):
"Returns the day of year."
- return self.__getDateInfo('R')
+ return self.__getdateinfo__('R')
@property
def month(self):
"Returns the month."
- return self.__getDateInfo('M')
+ return self.__getdateinfo__('M')
@property
def quarter(self):
"Returns the quarter."
- return self.__getDateInfo('Q')
+ return self.__getdateinfo__('Q')
@property
def year(self):
"Returns the year."
- return self.__getDateInfo('Y')
+ return self.__getdateinfo__('Y')
@property
def second(self):
"Returns the seconds."
- return self.__getDateInfo('S')
+ return self.__getdateinfo__('S')
@property
def minute(self):
"Returns the minutes."
- return self.__getDateInfo('T')
+ return self.__getdateinfo__('T')
@property
def hour(self):
"Returns the hour."
- return self.__getDateInfo('H')
+ return self.__getdateinfo__('H')
@property
def week(self):
"Returns the week."
- return self.__getDateInfo('I')
+ return self.__getdateinfo__('I')
- def __getDateInfo(self, info):
+ def __getdateinfo__(self, info):
return int(cseries.getDateInfo(numpy.asarray(self.value),
self.freq, info))
+ __getDateInfo = __getdateinfo__
def __add__(self, other):
if isinstance(other, Date):
@@ -497,24 +500,19 @@
>>> for d in DateArray(...):
accesses the array element by element. Therefore, `d` is a Date object.
"""
- def __new__(cls, dates=None, freq='U', copy=False):
- if isinstance(dates, DateArray):
- cls.__defaultfreq = dates.freq
- if not copy:
- return dates.view(cls)
- return dates.copy().view(cls)
+ (_tostr, _toord, _steps) = (None, None, None)
+ def __new__(cls, dates=None, freq=None, copy=False):
+ # Get the frequency ......
+ if freq is None:
+ _freq = getattr(dates, 'freq', -9999)
else:
- _dates = numeric.asarray(dates, dtype=int_)
- if _dates.ndim == 0:
- _dates.shape = (1,)
- if copy:
- _dates = _dates.copy()
- if freq is None:
- freq = 'U'
- cls.__defaultfreq = corelib.check_freq(freq)
- (cls.__toobj, cls.__toord, cls.__tostr) = (None, None, None)
- (cls.__steps, cls.__full, cls.__hasdups) = (None, None, None)
- return _dates.view(cls)
+ _freq = freq
+ cls._defaultfreq = corelib.check_freq(freq)
+ # Get the dates ..........
+ _dates = numeric.array(dates, copy=copy, dtype=int_, subok=1).view(cls)
+ if _dates.ndim == 0:
+ _dates.shape = (1,)
+ return _dates
def __array_wrap__(self, obj, context=None):
if context is None:
@@ -523,33 +521,26 @@
raise ArithmeticDateError, "(function %s)" % context[0].__name__
def __array_finalize__(self, obj):
- if hasattr(obj, 'freq'):
- self.freq = obj.freq
- self.freqstr = obj.freqstr
- else:
- self.freq = self.__defaultfreq
- self.freqstr = corelib.freq_tostr(self.__defaultfreq)
+ self.freq = getattr(obj, 'freq', self._defaultfreq)
+ self.freqstr = getattr(obj, 'freqstr', corelib.freq_tostr(self.freq))
+ for attr in ('_toobj','_toord','_tostr',
+ '_steps','_full','_hasdups'):
+ setattr(self, attr, getattr(obj, attr, None))
+ return
def __getitem__(self, indx):
if isinstance(indx, Date):
- index = self.find_dates(indx)
+ indx = self.find_dates(indx)
elif numeric.asarray(indx).dtype.kind == 'O':
try:
indx = self.find_dates(indx)
except AttributeError:
pass
r = ndarray.__getitem__(self, indx)
-# return r
- if not hasattr(r, "size"):
- if isinstance(r, int):
- return Date(self.freq, value=r)
- else:
- return r
- elif r.size == 1:
- # Only one element, and it's not a scalar: we have a DateArray of size 1
- if len(r.shape) > 0:
- r = r.item()
+ if isinstance(r, (generic, int)):
return Date(self.freq, value=r)
+ elif r.size == 1:
+ return Date(self.freq, value=r.item())
else:
return r
@@ -559,43 +550,43 @@
@property
def day(self):
"Returns the day of month."
- return self.__getDateInfo('D')
+ return self.__getDateInfo__('D')
@property
def day_of_week(self):
"Returns the day of week."
- return self.__getDateInfo('W')
+ return self.__getDateInfo__('W')
@property
def day_of_year(self):
"Returns the day of year."
- return self.__getDateInfo('R')
+ return self.__getDateInfo__('R')
@property
def month(self):
"Returns the month."
- return self.__getDateInfo('M')
+ return self.__getDateInfo__('M')
@property
def quarter(self):
"Returns the quarter."
- return self.__getDateInfo('Q')
+ return self.__getDateInfo__('Q')
@property
def year(self):
"Returns the year."
- return self.__getDateInfo('Y')
+ return self.__getDateInfo__('Y')
@property
def second(self):
"Returns the seconds."
- return self.__getDateInfo('S')
+ return self.__getDateInfo__('S')
@property
def minute(self):
"Returns the minutes."
- return self.__getDateInfo('T')
+ return self.__getDateInfo__('T')
@property
def hour(self):
"Returns the hour."
- return self.__getDateInfo('H')
+ return self.__getDateInfo__('H')
@property
def week(self):
"Returns the week."
- return self.__getDateInfo('I')
+ return self.__getDateInfo__('I')
days = day
weekdays = day_of_week
@@ -620,17 +611,17 @@
def toordinal(self):
"Converts the dates from values to ordinals."
# Note: we better try to cache the result
- if self.__toord is None:
+ if self._toord is None:
# diter = (Date(self.freq, value=d).toordinal() for d in self)
diter = (d.toordinal() for d in self)
toord = numeric.fromiter(diter, dtype=float_)
- self.__toord = toord
- return self.__toord
+ self._toord = toord
+ return self._toord
#
def tostring(self):
"Converts the dates to strings."
# Note: we better cache the result
- if self.__tostr is None:
+ if self._tostr is None:
firststr = str(self[0])
if self.size > 0:
ncharsize = len(firststr)
@@ -638,22 +629,18 @@
dtype='|S%i' % ncharsize)
else:
tostr = firststr
- self.__tostr = tostr
- return self.__tostr
+ self._tostr = tostr
+ return self._tostr
#
def asfreq(self, freq=None, relation="BEFORE"):
"Converts the dates to another frequency."
# Note: As we define a new object, we don't need caching
- if freq is None:
+ if freq is None or freq == -9999:
return self
tofreq = corelib.check_freq(freq)
if tofreq == self.freq:
return self
- if self.freqstr == 'U':
- warnings.warn("Undefined frequency: assuming daily!")
- fromfreq = corelib.freq_revdict['D']
- else:
- fromfreq = self.freq
+ fromfreq = self.freq
_rel = relation.upper()[0]
new = cseries.asfreq(numeric.asarray(self), fromfreq, tofreq, _rel)
return DateArray(new, freq=freq)
@@ -673,62 +660,54 @@
def date_to_index(self, date):
"Returns the index corresponding to one given date, as an integer."
- if isDate(date):
- if self.isvalid():
- index = date.value - self[0].value
- if index < 0 or index > self.size:
- raise ValueError, "Date out of bounds!"
- return index
- else:
- index_asarray = (self == date.value).nonzero()
- if fromnumeric.size(index_asarray) == 0:
- raise ValueError, "Date out of bounds!"
- return index_asarray[0][0]
+ if self.isvalid():
+ index = date.value - self[0].value
+ if index < 0 or index > self.size:
+ raise ValueError, "Date out of bounds!"
+ return index
else:
- #date is a DateArray
- def idx_check(val): return (date == val).any()
- idx_check_v = numpy.vectorize(idx_check)
- return numpy.where(idx_check_v(self.tovalue()))[0]
-
-
+ index_asarray = (self == date.value).nonzero()
+ if fromnumeric.size(index_asarray) == 0:
+ raise ValueError, "Date out of bounds!"
+ return index_asarray[0][0]
#......................................................
def get_steps(self):
"""Returns the time steps between consecutive dates.
The timesteps have the same unit as the frequency of the series."""
if self.freq == 'U':
- warnings.warn("Undefined frequency: assuming daily!")
- if self.__steps is None:
+ warnings.warn("Undefined frequency: assuming integers!")
+ if self._steps is None:
val = numeric.asarray(self).ravel()
if val.size > 1:
steps = val[1:] - val[:-1]
- if self.__full is None:
- self.__full = (steps.max() == 1)
- if self.__hasdups is None:
- self.__hasdups = (steps.min() == 0)
+ if self._full is None:
+ self._full = (steps.max() == 1)
+ if self._hasdups is None:
+ self._hasdups = (steps.min() == 0)
else:
- self.__full = True
- self.__hasdups = False
+ self._full = True
+ self._hasdups = False
steps = numeric.array([], dtype=int_)
- self.__steps = steps
- return self.__steps
+ self._steps = steps
+ return self._steps
def has_missing_dates(self):
"Returns whether the DateArray have missing dates."
- if self.__full is None:
+ if self._full is None:
steps = self.get_steps()
- return not(self.__full)
+ return not(self._full)
def isfull(self):
"Returns whether the DateArray has no missing dates."
- if self.__full is None:
+ if self._full is None:
steps = self.get_steps()
- return self.__full
+ return self._full
def has_duplicated_dates(self):
"Returns whether the DateArray has duplicated dates."
- if self.__hasdups is None:
+ if self._hasdups is None:
steps = self.get_steps()
- return self.__hasdups
+ return self._hasdups
def isvalid(self):
"Returns whether the DateArray is valid: no missing/duplicated dates."
@@ -958,7 +937,7 @@
"Returns the doc of the function (from the doc of the method)."
try:
return getattr(DateArray, self._methodname).__doc__
- except:
+ except AttributeError:
return "???"
#
def __call__(self, caller, *args, **params):
@@ -988,9 +967,14 @@
################################################################################
if __name__ == '__main__':
- assert (Date('D','2007-01')==Date('D',string='2007-01'))
- assert (Date('D','2007-01')==Date('D', value=732677))
- assert (Date('D',732677)==Date('D', value=732677))
- n = Date('D','2007-01')
- tmp = date_array(n,n+3)
- print tmp[0]
\ No newline at end of file
+ from maskedarray.testutils import assert_equal
+ if 1:
+ dlist = ['2007-%02i' % i for i in range(1,5)+range(7,13)]
+ mdates = date_array_fromlist(dlist, 'M')
+ # Using an integer
+ assert_equal(mdates[0].value, 24073)
+ assert_equal(mdates[-1].value, 24084)
+ # Using a date
+ lag = mdates.find_dates(mdates[0])
+ print mdates[lag]
+ assert_equal(mdates[lag], mdates[0])
\ No newline at end of file
Modified: trunk/Lib/sandbox/timeseries/tests/test_dates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tests/test_dates.py 2007-02-19 06:52:16 UTC (rev 2725)
+++ trunk/Lib/sandbox/timeseries/tests/test_dates.py 2007-02-19 07:37:26 UTC (rev 2726)
@@ -25,13 +25,18 @@
import maskedarray.testutils
from maskedarray.testutils import assert_equal, assert_array_equal
-from timeseries import tdates
-#reload(tdates)
+import timeseries.tdates as tdates
+reload(tdates)
+#from timeseries import tdates
+##reload(tdates)
+#from timeseries.tdates import date_array_fromlist, Date, DateArray, date_array,\
+# mxDFromString, today
+from timeseries.tdates import *
+from timeseries.tdates import mxDFromString
from timeseries import tcore
#reload(tcore)
-from timeseries.tdates import date_array_fromlist, Date, DateArray, date_array,\
- mxDFromString, today
+
class test_creation(NumpyTestCase):
"Base test class for MaskedArrays."
Modified: trunk/Lib/sandbox/timeseries/tests/test_timeseries.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tests/test_timeseries.py 2007-02-19 06:52:16 UTC (rev 2725)
+++ trunk/Lib/sandbox/timeseries/tests/test_timeseries.py 2007-02-19 07:37:26 UTC (rev 2726)
@@ -178,7 +178,8 @@
series.mask = nomask
assert(series._mask is nomask)
assert(series._series._mask is nomask)
- series._series.mask = [1,0,0]*5
+ #series._series.mask = [1,0,0]*5
+ series.mask = [1,0,0]*5
assert_equal(series._mask, [1,0,0]*5)
assert_equal(series._series._mask, [1,0,0]*5)
series[2] = masked
Modified: trunk/Lib/sandbox/timeseries/tseries.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tseries.py 2007-02-19 06:52:16 UTC (rev 2725)
+++ trunk/Lib/sandbox/timeseries/tseries.py 2007-02-19 07:37:26 UTC (rev 2726)
@@ -35,7 +35,7 @@
#from numpy.core.records import recarray
from numpy.core.records import fromarrays as recfromarrays
-import maskedarray as MA
+import maskedarray.core as MA
#reload(MA)
from maskedarray.core import MaskedArray, MAError, masked, nomask, \
filled, getmask, getmaskarray, make_mask_none, mask_or, make_mask, \
@@ -56,8 +56,6 @@
-
-
__all__ = [
'TimeSeriesError','TimeSeriesCompatibilityError','TimeSeries','isTimeSeries',
'time_series', 'tsmasked',
@@ -68,10 +66,10 @@
]
#...............................................................................
+#
+#ufunc_domain = {}
+#ufunc_fills = {}
-ufunc_domain = {}
-ufunc_fills = {}
-
#### --------------------------------------------------------------------------
#--- ... TimeSeriesError class ...
#### --------------------------------------------------------------------------
@@ -95,10 +93,11 @@
msg = "Incompatible starting dates! (%s <> %s)"
elif mode == 'size':
msg = "Incompatible sizes! (%s <> %s)"
+ else:
+ msg = "Incompatibility ! (%s <> %s)"
msg = msg % (first, second)
TimeSeriesError.__init__(self, msg)
-
#def _compatibilitycheck(a, b):
def _timeseriescompat(a, b):
"""Checks the date compatibility of two TimeSeries object.
@@ -193,6 +192,61 @@
##### --------------------------------------------------------------------------
##--- ... Time Series ...
##### --------------------------------------------------------------------------
+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.
+ """
+ def __init__ (self, methodname):
+ self._name = methodname
+ #
+ def __get__(self, obj, objtype=None):
+ "Gets the calling object."
+ self.obj = obj
+ return self
+ #
+ def __call__ (self, other, *args):
+ "Execute the call behavior."
+ instance = self.obj
+ if isinstance(other, TimeSeries):
+ assert(_timeseriescompat(instance, other))
+ func = getattr(super(TimeSeries, instance), self._name)
+ result = func(other, *args) #.view(type(instance))
+ result._dates = instance._dates
+ return result
+
+class _tsarraymethod(object):
+ """Defines a wrapper for basic array methods.
+When called, returns a new TimeSeries object, with the new series the result of
+the method applied on the original series.
+If `ondates` is True, the same operation is performed on the `_dates`.
+If `ondates` is False, the `_dates` part remains unchanged.
+ """
+ def __init__ (self, methodname, ondates=False):
+ """abfunc(fillx, filly) must be defined.
+ abinop(x, filly) = x for all x to enable reduce.
+ """
+ self._name = methodname
+ self._ondates = ondates
+ #
+ def __get__(self, obj, objtype=None):
+ self.obj = obj
+ return self
+ #
+ def __call__ (self, *args):
+ "Execute the call behavior."
+ _name = self._name
+ instance = self.obj
+ func_series = getattr(super(TimeSeries, instance), _name)
+ result = func_series(*args)
+ if self._ondates:
+ result._dates = getattr(instance._dates, _name)
+ else:
+ result._dates = instance._dates
+ return result
+
+
class TimeSeries(MaskedArray, object):
"""Base class for the definition of time series.
A time series is here defined as the combination of three arrays:
@@ -207,120 +261,62 @@
The combination of `series` and `dates` is the `data` part.
"""
options = None
+ _defaultobserved = None
def __new__(cls, data, dates=None, mask=nomask,
freq=None, observed=None, start_date=None,
dtype=None, copy=False, fill_value=None,
keep_mask=True, small_mask=True, hard_mask=False):
- #tslog.info("__new__: received data types %s, %s" % (type(data), data))
maparms = dict(copy=copy, dtype=dtype, fill_value=fill_value,
keep_mask=keep_mask, small_mask=small_mask,
- hard_mask=hard_mask, )
- if isinstance(data, TimeSeries):
- # Check dates ........
- if dates is None:
- newdates = data._dates
- else:
- if not hasattr(dates,'freq'):
- raise DateError, "Invalid Dates!"
- newdates = dates
- data._dates = newdates
- if hasattr(data, '_data') and hasattr(data._data, '_dates'):
- data._data._dates = newdates
- cls._defaultdates = newdates
- # Check frequency......
- if freq is not None:
- freq = corelib.check_freq(freq)
- if freq != newdates.freq:
- _dates = newdates.tofreq(freq)
- else:
- freq = newdates.freq
- # Check observed.......
- if observed is None:
- observed = data.observed
- else:
- observed = corelib.fmtObserv(observed)
- cls._defaultobserved = observed
- _data = data._series
+ hard_mask=hard_mask,)
+ # Get the data ...............................
+ _data = MaskedArray(data, mask=mask, **maparms).view(cls)
+ # Get the frequency ..........................
+ freq = corelib.check_freq(freq)
+ # Get the dates ..............................
+ if dates is None:
+ newdates = getattr(data, '_dates', None)
else:
- # Check dates ........
- if dates is None:
- length = _getdatalength(data)
- if length > 0:
- newdates = date_array(start_date=start_date, length=length,
- freq=freq)
- else:
- newdates = date_array([], freq=freq)
- elif not hasattr(dates, 'freq'):
+ newdates = dates
+ if newdates is not None:
+ if not hasattr(newdates, 'freq'):
newdates = date_array(dlist=dates, freq=freq)
+ if freq is not None and newdates.freq != freq:
+ newdates = newdates.tofreq(freq)
+ else:
+ length = _getdatalength(data)
+ if length > 0:
+ newdates = date_array(start_date=start_date, length=length,
+ freq=freq)
else:
- newdates = dates
- # Check data .........
- _data = data
- if hasattr(data, '_mask') :
- mask = mask_or(data._mask, mask)
- # Set default ........
- cls._defaultdates = newdates
- cls._defaultobserved = corelib.fmtObserv(observed)
-
+ newdates = date_array([], freq=freq)
+ # Get observed ...............................
+ observed = getattr(data, 'observed', corelib.fmtObserv(observed))
+
if _data is masked:
assert(numeric.size(newdates)==1)
return _data.view(cls)
- newdata = super(TimeSeries,cls).__new__(cls, _data, mask=mask,
- **maparms)
- assert(_datadatescompat(newdata._data,newdates))
- return newdata
-
- #..................................
- def __array_wrap__(self, obj, context=None):
- return TimeSeries(super(TimeSeries,self).__array_wrap__(obj, context),
- dates=self._dates)
+ assert(_datadatescompat(_data,newdates))
+ _data._dates = newdates
+ _data._defaultdates = _data._dates
+ return _data
#............................................
def __array_finalize__(self,obj):
- #tslog.info("__array_finalize__ received %s" % type(obj))
- if isinstance(obj, TimeSeries):
- self._dates = obj._dates
- self._data = obj._series._data
- self._mask = obj._series._mask
- self._series = obj._series
- self._hardmask = obj._series._hardmask
- self.observed = obj.observed
- self._fill_value = obj._fill_value
- else:
- self._dates = self._defaultdates
- self.observed = self._defaultobserved
- self._data = obj
- self._mask = self._defaultmask
- if obj is masked:
- self._series = masked
- else:
- self._series = MA.array(obj, mask=self._defaultmask,
- copy=False, hard_mask=self._defaulthardmask)
- self._hardmask = self._defaulthardmask
- self.fill_value = self._fill_value
- self._mask = self._series._mask
- self._data = self._series._data
- self._hardmask = self._series._hardmask
- #
- TimeSeries._defaulthardmask = False
- TimeSeries._defaultmask = nomask
- #tslog.info("__array_finalize__ sends %s" % type(self))
+ MaskedArray.__array_finalize__(self, obj)
+ self._dates = getattr(obj, '_dates', None)
+ self.observed = getattr(obj, 'observed', self._defaultobserved)
return
+ #..................................
+ def __array_wrap__(self, obj, context=None):
+ result = super(TimeSeries, self).__array_wrap__(obj, context)
+ result._dates = self._dates
+ return result
#............................................
- def __getattribute__(self,attr):
- "Returns a given attribute."
- # Here, we need to be smart: _mask should call _series._mask...
- if attr in ['_data','_mask','_hardmask']:
- return getattr(self._series,attr)
- return super(TimeSeries, self).__getattribute__(attr)
-
- def __setattribute__(self,attr, value):
- """Sets an attribute to a given value."""
- # Same thing here: if we modify ._mask, we need to modify _series._mask
- # ...as well
- super(TimeSeries, self).__setattribute__(attr, value)
- if attr in ['_data','_mask','_hardmask']:
- super(self._series.__class__, self._series).__setattribute__(attr, value)
- setattr(self._series, attr, value)
+ def _get_series(self):
+ if self._mask.ndim == 0 and self._mask:
+ return masked
+ return self.view(MaskedArray)
+ _series = property(fget=_get_series)
#............................................
def __checkindex(self, indx):
"Checks the validity of an index."
@@ -397,43 +393,25 @@
raise MAError, 'Cannot alter the masked element.'
(sindx, dindx) = self.__checkindex(indx)
#....
- if value is tsmasked:
- self._series[sindx] = masked
- elif isinstance(value, TimeSeries):
- assert(_timeseriescompat(self[sindx], value))
- self._series[sindx] = value._series
- else:
- self._series[sindx] = value
- # Don't forget to update the mask !
- self._mask = self._series._mask
-
+ super(TimeSeries, self).__setitem__(sindx, value)
#........................
def __getslice__(self, i, j):
"Gets slice described by i, j"
(si,di) = self.__checkindex(i)
(sj,dj) = self.__checkindex(j)
- (data, date) = (self._series[si:sj], self._dates[di:dj])
- return TimeSeries(data, dates=date, copy=False)
+ result = super(TimeSeries, self).__getitem__(slice(si,sj))
+ result._dates = self._dates[di:dj]
+ return result
#....
def __setslice__(self, i, j, value):
"Gets item described by i. Not a copy as in previous versions."
- (si,di) = self.__checkindex(i)
- (sj,dj) = self.__checkindex(j)
+ (si,_) = self.__checkindex(i)
+ (sj,_) = self.__checkindex(j)
#....
-# data = self._series[i:j]
if isinstance(value, TimeSeries):
assert(_timeseriescompat(self[si:sj], value))
- self._series[si:sj] = value._series
- else:
- self._series[si:sj] = value
- # Don't forget to update the mask !
- self._mask = self._series._mask
+ super(TimeSeries, self).__setitem__(slice(si,sj), value)
#......................................................
- def __len__(self):
- if self.ndim == 0:
- return 0
- return ndarray.__len__(self)
- #......................................................
def __str__(self):
"""Returns a string representation of self (w/o the dates...)"""
return str(self._series)
@@ -466,30 +444,46 @@
'time': timestr,
'freq': self.freqstr, }
#............................................
- def _get_mask(self):
- """Returns the current mask."""
- return self._series._mask
- def _set_mask(self, mask):
- """Sets the mask to `mask`."""
- mask = make_mask(mask, copy=False, small_mask=True)
- if mask is not nomask:
- if mask.size != self._data.size:
- raise ValueError, "Inconsistent shape between data and mask!"
- if mask.shape != self._data.shape:
- mask.shape = self._data.shape
- self._series._mask = mask
- else:
- self._series._mask = nomask
- mask = property(fget=_get_mask, fset=_set_mask, doc="Mask")
-
+ __add__ = _tsmathmethod('__add__')
+ __radd__ = _tsmathmethod('__add__')
+ __sub__ = _tsmathmethod('__sub__')
+ __rsub__ = _tsmathmethod('__rsub__')
+ __pow__ = _tsmathmethod('__pow__')
+ __mul__ = _tsmathmethod('__mul__')
+ __rmul__ = _tsmathmethod('__mul__')
+ __div__ = _tsmathmethod('__div__')
+ __rdiv__ = _tsmathmethod('__rdiv__')
+ __truediv__ = _tsmathmethod('__truediv__')
+ __rtruediv__ = _tsmathmethod('__rtruediv__')
+ __floordiv__ = _tsmathmethod('__floordiv__')
+ __rfloordiv__ = _tsmathmethod('__rfloordiv__')
+ __eq__ = _tsmathmethod('__eq__')
+ __ne__ = _tsmathmethod('__ne__')
+ __lt__ = _tsmathmethod('__lt__')
+ __le__ = _tsmathmethod('__le__')
+ __gt__ = _tsmathmethod('__gt__')
+ __ge__ = _tsmathmethod('__ge__')
+
+ astype = _tsarraymethod('astype')
+ reshape = _tsarraymethod('reshape', ondates=True)
+ copy = _tsarraymethod('copy', ondates=True)
+ compress = _tsarraymethod('compress', ondates=True)
+ ravel = _tsarraymethod('ravel', ondates=True)
+ cumsum = _tsarraymethod('cumsum',ondates=False)
+ cumprod = _tsarraymethod('cumprod',ondates=False)
+ anom = _tsarraymethod('anom',ondates=False)
+
+# def nonzero(self):
+# """Returns a tuple of ndarrays, one for each dimension of the array,
+# containing the indices of the non-zero elements in that dimension."""
+# return self._series.nonzero()
+
+# filled = _tsarraymethod('filled', ondates=False)
+
+ #............................................
def ids (self):
"""Return the ids of the data, dates and mask areas"""
- return (id(self._series), id(self.dates),)
-
- def copy(self):
- "Returns a copy of the TimeSeries."
- return TimeSeries(self, copy=True)
-
+ return (id(self._series), id(self.dates),)
#------------------------------------------------------
@property
def series(self):
@@ -507,7 +501,6 @@
def freqstr(self):
"""Returns the corresponding frequency (as a string)."""
return self._dates.freqstr
-
@property
def day(self):
"Returns the day of month for each date in self._dates."
@@ -605,10 +598,6 @@
"Converts the dates to another frequency, and adapt the data."
return convert(self, freq, func=func, position=position)
#.....................................................
- def nonzero(self):
- """Returns a tuple of ndarrays, one for each dimension of the array,
- containing the indices of the non-zero elements in that dimension."""
- return self._series.nonzero()
def _attrib_dict(series, exclude=[]):
"""this function is used for passing through attributes of one
@@ -621,128 +610,7 @@
##### --------------------------------------------------------------------------
##--- ... Additional methods ...
##### --------------------------------------------------------------------------
-class _inplacemethod(object):
- """Defines a wrapper for inplace arithmetic array methods (iadd, imul...).
-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, binop):
- """abfunc(fillx, filly) must be defined.
- abinop(x, filly) = x for all x to enable reduce.
- """
- self.f = binop
- self.obj = None
- #
- def __get__(self, obj, objtype=None):
- "Gets the calling object."
- self.obj = obj
- return self
- #
- def __call__ (self, other, *args):
- "Execute the call behavior."
- instance = self.obj
- assert(_timeseriescompat(instance,other))
- func = getattr(instance._series, self.f)
- func(other, *args)
- return instance
-#......................................
-TimeSeries.__iadd__ = _inplacemethod('__iadd__')
-TimeSeries.__iand__ = _inplacemethod('__iand__')
-TimeSeries.__idiv__ = _inplacemethod('__idiv__')
-TimeSeries.__isub__ = _inplacemethod('__isub__')
-TimeSeries.__imul__ = _inplacemethod('__imul__')
-
-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.
- """
- def __init__ (self, binop):
- """abfunc(fillx, filly) must be defined.
- abinop(x, filly) = x for all x to enable reduce.
- """
- self.f = binop
- #
- def __get__(self, obj, objtype=None):
- "Gets the calling object."
- self.obj = obj
- return self
- #
- def __call__ (self, other, *args):
- "Execute the call behavior."
- instance = self.obj
- _dates = instance._dates
- #tslog.info("_tsmathmethod: series: %s" % instance,)
- #tslog.info("_tsmathmethod: other : %s" % other,)
- func = getattr(instance._series, self.f)
- if isinstance(other, TimeSeries):
- assert(_timeseriescompat(instance, other))
- return instance.__class__(func(other, *args), dates=_dates,)
-#......................................
-TimeSeries.__add__ = _tsmathmethod('__add__')
-TimeSeries.__radd__ = _tsmathmethod('__add__')
-TimeSeries.__sub__ = _tsmathmethod('__sub__')
-TimeSeries.__rsub__ = _tsmathmethod('__rsub__')
-TimeSeries.__pow__ = _tsmathmethod('__pow__')
-TimeSeries.__mul__ = _tsmathmethod('__mul__')
-TimeSeries.__rmul__ = _tsmathmethod('__mul__')
-TimeSeries.__div__ = _tsmathmethod('__div__')
-TimeSeries.__rdiv__ = _tsmathmethod('__rdiv__')
-TimeSeries.__truediv__ = _tsmathmethod('__truediv__')
-TimeSeries.__rtruediv__ = _tsmathmethod('__rtruediv__')
-TimeSeries.__floordiv__ = _tsmathmethod('__floordiv__')
-TimeSeries.__rfloordiv__ = _tsmathmethod('__rfloordiv__')
-TimeSeries.__eq__ = _tsmathmethod('__eq__')
-TimeSeries.__ne__ = _tsmathmethod('__ne__')
-TimeSeries.__lt__ = _tsmathmethod('__lt__')
-TimeSeries.__le__ = _tsmathmethod('__le__')
-TimeSeries.__gt__ = _tsmathmethod('__gt__')
-TimeSeries.__ge__ = _tsmathmethod('__ge__')
-#................................................
-class _tsarraymethod(object):
- """Defines a wrapper for basic array methods.
-When called, returns a new TimeSeries object, with the new series the result of
-the method applied on the original series.
-If `ondates` is True, the same operation is performed on the `_dates`.
-If `ondates` is False, the `_dates` part remains unchanged.
- """
- def __init__ (self, methodname, ondates=False):
- """abfunc(fillx, filly) must be defined.
- abinop(x, filly) = x for all x to enable reduce.
- """
- self._name = methodname
- self._ondates = ondates
- #
- def __get__(self, obj, objtype=None):
- self.obj = obj
- return self
- #
- def __call__ (self, *args):
- "Execute the call behavior."
- _name = self._name
- instance = self.obj
- func_series = getattr(instance._series, _name)
- if self._ondates:
- func_dates = getattr(instance._dates, _name)
- return instance.__class__(func_series(*args),
- dates=func_dates(*args))
- else:
- return instance.__class__(func_series(*args),
- dates=instance._dates)
-TimeSeries.astype = _tsarraymethod('astype')
-TimeSeries.reshape = _tsarraymethod('reshape', ondates=True)
-TimeSeries.copy = _tsarraymethod('copy', ondates=True)
-TimeSeries.compress = _tsarraymethod('compress', ondates=True)
-TimeSeries.ravel = _tsarraymethod('ravel', ondates=True)
-TimeSeries.filled = _tsarraymethod('filled', ondates=False)
-TimeSeries.cumsum = _tsarraymethod('cumsum',ondates=False)
-TimeSeries.cumprod = _tsarraymethod('cumprod',ondates=False)
-TimeSeries.anom = _tsarraymethod('anom',ondates=False)
-
-#......................................
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.
@@ -982,6 +850,7 @@
`data` :
Array of data.
"""
+ data = numeric.asanyarray(data)
if dates is None:
length = _getdatalength(data)
if length > 0:
@@ -1375,12 +1244,6 @@
data = MA.asarray(data)
newdatad = numeric.empty(nsize, data.dtype)
newdatam = numeric.ones(nsize, bool_)
-# if fill_value is None:
-# if hasattr(data,'fill_value'):
-# fill_value = data.fill_value
-# else:
-# fill_value = MA.default_fill_value(data)
- #data = data.filled(fill_value)
#....
if datam is nomask:
for (new,old) in zip(newslc,oldslc):
@@ -1448,19 +1311,6 @@
if __name__ == '__main__':
from maskedarray.testutils import assert_equal
import numpy as N
+
+
- if 1:
- #TODO: CHECK THAT, AND PUT IT IN tests/test_timeseries IF IT WORKS
- # Test 2 points of 3 variables
- xx = time_series([[1,2,3],[4,5,6]], start_date=thisday('b'))
- assert_equal(xx[0]._data, [[1,2,3]])
- assert_equal(xx[:,0]._data, [1,4])
- # Test a single point of 3 variables
- xx = time_series([[1,2,3]], start_date=thisday('b'))
- assert_equal(xx[0]._data, [[1,2,3]])
- assert_equal(xx[:,0]._data, [[1]])
- # Test 3 data points
- x = time_series([1,2,3], start_date=thisday('b'))
- assert_equal(x[0], 1)
- # Test using a DateArray as items
- assert_equal(x[x._dates[:]],x)
More information about the Scipy-svn
mailing list