[Scipy-svn] r2760 - trunk/Lib/sandbox/timeseries
scipy-svn at scipy.org
scipy-svn at scipy.org
Sun Feb 25 21:55:03 EST 2007
Author: pierregm
Date: 2007-02-25 20:54:59 -0600 (Sun, 25 Feb 2007)
New Revision: 2760
Modified:
trunk/Lib/sandbox/timeseries/__init__.py
trunk/Lib/sandbox/timeseries/tdates.py
trunk/Lib/sandbox/timeseries/tseries.py
Log:
tseries : forced a singleton to have a DateArray _dates
: added empty_like, where dates are copied from the model
tdates : reset the default freq to -9999 in DateArray.__array_finalize__
: DateArray: put the cached info in a single directory '_cachedinfo'
: fixed illegal propagation of cachedinfo
: made freqstr a property
__init__: added import plotlib
Modified: trunk/Lib/sandbox/timeseries/__init__.py
===================================================================
--- trunk/Lib/sandbox/timeseries/__init__.py 2007-02-23 21:20:19 UTC (rev 2759)
+++ trunk/Lib/sandbox/timeseries/__init__.py 2007-02-26 02:54:59 UTC (rev 2760)
@@ -22,7 +22,8 @@
import tmulti
from tmulti import *
import reportlib
-from reportlib import *
+from reportlib import *
+import plotlib
__all__ = ['tdates', 'tseries','tmulti','reportlib']
__all__ += tdates.__all__
Modified: trunk/Lib/sandbox/timeseries/tdates.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tdates.py 2007-02-23 21:20:19 UTC (rev 2759)
+++ trunk/Lib/sandbox/timeseries/tdates.py 2007-02-26 02:54:59 UTC (rev 2760)
@@ -550,7 +550,8 @@
>>> for d in DateArray(...):
accesses the array element by element. Therefore, `d` is a Date object.
"""
- (_tostr, _toord, _steps) = (None, None, None)
+ _defcachedinfo = dict(toobj=None, tostr=None, toord=None,
+ steps=None, full=None, hasdups=None)
def __new__(cls, dates=None, freq=None, copy=False):
# Get the frequency ......
if freq is None:
@@ -573,11 +574,11 @@
raise ArithmeticDateError, "(function %s)" % context[0].__name__
def __array_finalize__(self, obj):
- 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))
+ self.freq = getattr(obj, 'freq', -9999)
+ self._cachedinfo = dict(toobj=None, tostr=None, toord=None,
+ steps=None, full=None, hasdups=None)
+ if hasattr(obj,'_cachedinfo'):
+ self._cachedinfo.update(obj._cachedinfo)
return
def __getitem__(self, indx):
@@ -598,6 +599,10 @@
# behaviour
return Date(self.freq, value=r.item())
else:
+ r._cachedinfo.update(dict(steps=None, full=None, hasdups=None))
+ for attr in ('tostr','toobj','toord'):
+ if r._cachedinfo[attr] is not None:
+ r._cachedinfo[attr] = r._cachedinfo[attr][indx]
return r
def __repr__(self):
@@ -615,6 +620,10 @@
__ne__ = _datearithmetics('__ne__', asdates=False)
#......................................................
@property
+ def freqstr(self):
+ "Returns the frequency string code."
+ return corelib.freq_tostr(self.freq)
+ @property
def day(self):
"Returns the day of month."
return self.__getdateinfo__('D')
@@ -667,7 +676,9 @@
weeks = week
def __getdateinfo__(self, info):
- return numeric.asarray(cseries.getDateInfo(numeric.asarray(self), self.freq, info), dtype=int_)
+ return numeric.asarray(cseries.getDateInfo(numeric.asarray(self),
+ self.freq, info),
+ dtype=int_)
__getDateInfo = __getdateinfo__
#.... Conversion methods ....................
#
@@ -678,17 +689,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._cachedinfo['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._cachedinfo['toord'] = toord
+ return self._cachedinfo['toord']
#
def tostring(self):
"Converts the dates to strings."
# Note: we better cache the result
- if self._tostr is None:
+ if self._cachedinfo['tostr'] is None:
firststr = str(self[0])
if self.size > 0:
ncharsize = len(firststr)
@@ -696,8 +707,8 @@
dtype='|S%i' % ncharsize)
else:
tostr = firststr
- self._tostr = tostr
- return self._tostr
+ self._cachedinfo['tostr'] = tostr
+ return self._cachedinfo['tostr']
#
def asfreq(self, freq=None, relation="BEFORE"):
"Converts the dates to another frequency."
@@ -743,38 +754,39 @@
The timesteps have the same unit as the frequency of the series."""
if self.freq == 'U':
warnings.warn("Undefined frequency: assuming integers!")
- if self._steps is None:
+ if self._cachedinfo['steps'] is None:
+ _cached = self._cachedinfo
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 _cached['full'] is None:
+ _cached['full'] = (steps.max() == 1)
+ if _cached['hasdups'] is None:
+ _cached['hasdups'] = (steps.min() == 0)
else:
- self._full = True
- self._hasdups = False
+ _cached['full'] = True
+ _cached['hasdups'] = False
steps = numeric.array([], dtype=int_)
- self._steps = steps
- return self._steps
+ self._cachedinfo['steps'] = steps
+ return self._cachedinfo['steps']
def has_missing_dates(self):
"Returns whether the DateArray have missing dates."
- if self._full is None:
+ if self._cachedinfo['full'] is None:
steps = self.get_steps()
- return not(self._full)
+ return not(self._cachedinfo['full'])
def isfull(self):
"Returns whether the DateArray has no missing dates."
- if self._full is None:
+ if self._cachedinfo['full'] is None:
steps = self.get_steps()
- return self._full
+ return self._cachedinfo['full']
def has_duplicated_dates(self):
"Returns whether the DateArray has duplicated dates."
- if self._hasdups is None:
+ if self._cachedinfo['hasdups'] is None:
steps = self.get_steps()
- return self._hasdups
+ return self._cachedinfo['hasdups']
def isvalid(self):
"Returns whether the DateArray is valid: no missing/duplicated dates."
@@ -996,6 +1008,7 @@
################################################################################
if __name__ == '__main__':
+ import maskedarray.testutils
from maskedarray.testutils import assert_equal
if 1:
dlist = ['2007-%02i' % i for i in range(1,5)+range(7,13)]
@@ -1019,4 +1032,11 @@
print f
today = thisday(f)
assert(Date(freq=f, value=today.value) == today)
+
+ if 1:
+ D = date_array(start_date=thisday('D'), length=5)
+ Dstr = D.tostring()
+ assert_equal(D.tostring(), Dstr)
+ DL = D[[0,-1]]
+ assert_equal(DL.tostring(), Dstr[[0,-1]])
\ No newline at end of file
Modified: trunk/Lib/sandbox/timeseries/tseries.py
===================================================================
--- trunk/Lib/sandbox/timeseries/tseries.py 2007-02-23 21:20:19 UTC (rev 2759)
+++ trunk/Lib/sandbox/timeseries/tseries.py 2007-02-26 02:54:59 UTC (rev 2760)
@@ -291,7 +291,7 @@
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):
+ keep_mask=True, small_mask=True, hard_mask=False, **options):
maparms = dict(copy=copy, dtype=dtype, fill_value=fill_value,
keep_mask=keep_mask, small_mask=small_mask,
hard_mask=hard_mask,)
@@ -394,6 +394,7 @@
m = self._mask
singlepoint = (len(numeric.shape(newdate))==0)
if singlepoint:
+ newdate = DateArray(newdate)
if newdata is masked:
newdata = tsmasked
newdata._dates = newdate
@@ -655,20 +656,36 @@
return convert(self, freq, func=func, position=position)
#.....................................................
def transpose(self, *axes):
+ """ a.transpose(*axes)
+
+ 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.
+
+ """
if self._dates.size == self.size:
result = super(TimeSeries, self).transpose(*axes)
result._dates = self._dates.transpose(*axes)
else:
errmsg = "Operation not permitted on multi-variable series"
- print "AXES:",axes
if (len(axes)==0) or axes[0] != 0:
- raise ValueError, errmsg
+ raise TimeSeriesError, errmsg
else:
result = super(TimeSeries, self).transpose(*axes)
result._dates = self._dates
return result
+ #......................................................
+ def copy_attributes(self, oldseries, exclude=[]):
+ "Copies the attributes from oldseries if they are not in the exclude list."
+ attrlist = ['fill_value', 'observed']
+ 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))
-
def _attrib_dict(series, exclude=[]):
"""this function is used for passing through attributes of one
@@ -676,7 +693,7 @@
result = {'fill_value':series.fill_value,
'observed':series.observed}
return dict(filter(lambda x: x[0] not in exclude, result.iteritems()))
-
+
##### --------------------------------------------------------------------------
##--- ... Additional methods ...
@@ -1061,14 +1078,14 @@
newshape[0] = len(newdates)
newshape = tuple(newshape)
- newdata = masked_array(numeric.empty(newshape, dtype=a.dtype), mask=True)
- #backup the series attributes
- options = dict(fill_value=a.fill_value, observed=a.observed)
- newseries = TimeSeries(newdata, newdates, **options)
+ newseries = numeric.empty(newshape, dtype=a.dtype).view(type(a))
+ newseries.__setmask__(numeric.ones(newseries.shape, dtype=bool_))
+ newseries._dates = newdates
if dstart is not None:
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)
return newseries
#....................................................................
def align_series(*series, **kwargs):
@@ -1105,7 +1122,7 @@
aligned = align_series
#....................................................................
def convert(series, freq, func='auto', position='END'):
- """Converts a series to a frequency
+ """Converts a series to a frequency.
When converting to a lower frequency, func is a function that acts
on a 1-d array and returns a scalar or 1-d array. func should handle
@@ -1156,12 +1173,20 @@
if tempData.ndim == 2 and func is not None:
tempData = MA.apply_along_axis(func, -1, tempData)
-
- newseries = TimeSeries(tempData, freq=toFreq,
- observed=series.observed,
- start_date=start_date)
+
+ newseries = tempData.view(type(series))
+ newseries._dates = date_array(start_date=start_date, length=len(newseries),
+ freq=toFreq)
+ newseries.copy_attributes(series)
return newseries
+
+def group_byperiod(series, freq, func='auto', position='END'):
+ """Converts a series to a frequency, without any processing.
+ """
+ return convert(series, freq, func=None, position='END')
+
TimeSeries.convert = convert
+TimeSeries.group_byperiod = group_byperiod
#...............................................................................
def tshift(series, nper, copy=True):
@@ -1207,7 +1232,9 @@
newdata[:-nper] = inidata[nper:]
else:
newdata = inidata
- newseries = TimeSeries(newdata, series._dates, **options)
+ newseries = newdata.view(type(series))
+ newseries._dates = series._dates
+ newseries.copy_attributes(series)
return newseries
TimeSeries.tshift = tshift
#...............................................................................
@@ -1339,7 +1366,12 @@
else:
newdata[~keeper] = 0
return newseries
-
+#...............................................................................
+def empty_like(series):
+ result = N.empty_like(series).view(type(series))
+ result._dates = series._dates
+ result._mask = series._mask
+ return result
################################################################################
if __name__ == '__main__':
@@ -1361,13 +1393,21 @@
sertrans = serfolded.transpose()
assert_equal(sertrans.shape, (2,5))
- assert ser1d[0] is tsmasked
- print "OK"
if 1:
hodie = today('D')
ser2d = time_series(N.arange(10).reshape(5,2), start_date=hodie,
mask=[[1,1],[0,0],[0,0],[0,0],[0,0]])
+ try:
+ ser2d_transpose = ser2d.transpose()
+ except TimeSeriesError:
+ pass
if 1:
hodie = today('D')
ser3d = time_series(N.arange(30).reshape(5,3,2), start_date=hodie,)
+ try:
+ ser3d_transpose = ser3d.transpose()
+ except TimeSeriesError:
+ pass
+ assert_equal(ser3d.transpose(0,2,1).shape, (5,2,3))
+
More information about the Scipy-svn
mailing list