.. currentmodule:: scikits.timeseries ============================ :class:`~TimeSeries` objects ============================ .. class:: TimeSeries A subclass of :class:`~numpy.ma.MaskedArray` designed to manipulate time series. :Parameters: **data** : {array_like} Data portion of the array. Any data that is valid for constructing a :class:`~numpy.ma.MaskedArray` can be used here: * a sequence of objects (numbers, characters, objects); * a :class:`~numpy.ndarray` or one of its subclass. In particular, :class:`~numpy.ma.MaskedArray` and :class:`TimeSeries` are recognized. **dates** : {DateArray} A :class:`DateArray` instance storing the date information. **autosort** : {True, False}, optional Whether to sort the series in chronological order. **\*\*optional_parameters** : All the parameters recognized by :class:`~numpy.ma.MaskedArray` are also recognized by :class:`TimeSeries`. .. seealso:: :class:`~numpy.ma.MaskedArray` A :class:`~TimeSeries` object is the combination of three ndarrays: * :attr:`dates`: A :class:`~DateArray` object. * :attr:`data` : A :class:`~numpy.ndarray`. * :attr:`mask` : A boolean :class:`~numpy.ndarray`, indicating missing or invalid data. These three arrays can be accessed as attributes of a :class:`~TimeSeries` object. Another very useful attribute is :attr:`series`, that gives the possibility to directly access :attr:`data` and :attr:`mask` as a masked array. As :class:`TimeSeries` objects subclass :class:`~numpy.ma.MaskedArray`, they inherit all their attributes and methods, as well as the attributes and methods of regular ndarrays. Attributes ========== ... specific to :class:`TimeSeries` ----------------------------------- .. attribute:: data Returns a view of a :class:`TimeSeries` as a :class:`~numpy.ndarray`. This attribute is read-only and cannot be directly set. .. attribute:: mask Returns the mask of the object, as a :class:`~numpy.ndarray` with the same shape as :attr:`data`, or as the special value :data:`~numpy.ma.nomask` (equivalent to :const:`False`). This attribute is writable and can be modified. If :attr:`data` has a standard :attr:`~numpy.dtype` (no named fields), the :attr:`~numpy.dtype` of the mask is boolean. If :attr:`data` is a structured array with named fields, the mask has the same structure as the :attr:`data`\'s, but each field is atomically boolean. In any case, a value of :const:`True` in the mask indicates that the corresponding value of the series is invalid. .. attribute:: series Returns a view of a :class:`TimeSeries` as a :class:`~numpy.ma.MaskedArray`. This attribute is read-only and cannot be directly set .. attribute:: dates Returns the :class:`DateArray` object of the dates of the series. This attribute is writable and can be modified. However, the size of the array must be zero or match either the size of the series or its length. .. attribute:: varshape Returns the number of equivalent variables for each date. If ``varshape == ()``, the series has only one variable and is called a 1V-series. ... direct access to the :attr:`dates` information -------------------------------------------------- ============================== =========================== :attr:`~DateArray.freq` :attr:`~DateArray.freqstr` :attr:`~DateArray.year` :attr:`~DateArray.years` :attr:`~DateArray.qyear` :attr:`~DateArray.quarter` :attr:`~DateArray.quarters` :attr:`~DateArray.month` :attr:`~DateArray.months` :attr:`~DateArray.week` :attr:`~DateArray.weeks` :attr:`~DateArray.day` :attr:`~DateArray.days` :attr:`~DateArray.day_of_week` :attr:`~DateArray.weekdays` :attr:`~DateArray.day_of_year` :attr:`~DateArray.yeardays` :attr:`~DateArray.hour` :attr:`~DateArray.hours` :attr:`~DateArray.minute` :attr:`~DateArray.minutes` :attr:`~DateArray.second` :attr:`~DateArray.seconds` :attr:`~DateArray.start_date` :attr:`~DateArray.end_date` ============================== =========================== ... inherited from :class:`~numpy.ma.MaskedArray` ------------------------------------------------- .. autosummary:: :toctree: generated/ TimeSeries.fill_value TimeSeries.baseclass TimeSeries.recordmask TimeSeries.hardmask TimeSeries.sharedmask ... inherited from :class:`~numpy.ndarray` ------------------------------------------ .. autosummary:: :toctree: generated/ TimeSeries.base TimeSeries.ctypes TimeSeries.dtype TimeSeries.flags TimeSeries.itemsize TimeSeries.nbytes TimeSeries.ndim TimeSeries.shape TimeSeries.size TimeSeries.strides TimeSeries.imag TimeSeries.real TimeSeries.flat Construction ============ To construct a :class:`~TimeSeries` object, the simplest method is to directly call the class constructor with the proper parameters. However, the recommended way is to use the :func:`~time_series` factory function. .. autofunction:: time_series .. note:: By default, the series is automatically sorted in chronological order. This behavior can be overwritten by setting the keyword ``autosort=False``. Dates and data compatibility ---------------------------- The simplest example of a :class:`TimeSeries` consists in a series ``series`` of one variable, where a date is associated with each element of the array. In that case, the :attr:`dates` attribute is a :class:`DateArray` with the same size as the underlying array. For example, we can create a 4-element series: >>> first_date = ts.Date('D', '2009-01-01') >>> series = ts.time_series([1, 2, 3, 4], start_date=first_date) >>> series timeseries([1 2 3 4], dates = [01-Jan-2009 ... 04-Jan-2009], freq = D) Note that with the use of the :keyword:`start_date` keyword, the size of the :attr:`dates` attribute is automatically adjusted by :func:`time_series` to match the size of the input data. The :attr:`dates` can now be modified in place. For example, they can be shifted by one week with the following command. >>> series.dates +=7 >>> series timeseries([1 2 3 4], dates = [08-Jan-2009 ... 11-Jan-2009], freq = D) The dates can also be changed by setting the :attr:`dates` attribute to another :class:`DateArray` object. In that case, the size of the new dates must match the size of the series, or a :exc:`TimeSeriesCompatibilityError` is raised. Setting the :attr:`dates` attribute to an object of a different type raises a :exc:`TypeError` exception. It is often convenient to manipulate a series of several variables at once. Once possibility is to use a `structured array <http://docs.scipy.org/doc/numpy/user/basics.rec.html>`_ as input, as illustrated by the following example: >>> series = ts.time_series(zip(np.random.normal(0, 1, 10), ... np.random.uniform(0, 1, 10)), ... dtype=[('norm', float), ('unif', float)], ... start_date=ts.Date('D', '2001-01-01')) In this example, ``series`` consists of two fields (`'norm'` and `'unif'`). Note that in this example, the two fields have the same type (:class:`~numpy.float`), but this is not a requirement. Each field can be accessed as an independent :class:`TimeSeries` using ``series['norm']`` and ``series['unif']``. In practice, each individual entry of ``series`` is a :class:`numpy.void` object. The series as a whole behaves as a 1D masked array, as represented by the :attr:`shape` of the series: ``series.shape = (10,)``. Because ``series`` is a 1D array, the size of ``series.dates`` must match ``series.size``. Despite the convenience of this approach to manipulate multi-variable series, it presents a serious disadvantage: structured arrays are usually not recognized by standard numpy functions. An alternative is then to represent a series as a two-dimensional array, using columns as variables and rows as actual obervations. In that case, all the variables must have the same type, and the size of the :attr:`dates` attibute must match the length of the series. More generally, it is possible to create a multi-variable series as a nD array. The corresponding dates must then satisfy the condition ``series.dates.size == series.shape[0]`` or a :exc:`TimeSeriesCompatibilityError` is raised. The specific attribute :attr:`varshape` is then set to keep track of the number of variables. For example, a series of 50 years of monthly data can be represented as a (600,)-array of observations at a monthly frequency, or as a (50,12)-array of observations at an annual frequency. >>> start - ts.Date('M', '2001-01') >>> data = np.random.uniform(-1, +1, 50*12).reshape(50, 12) >>> mseries = ts.time_series(data, start_date=start, length=50*12) >>> aseries = ts.time_series(data, start_date=start.asfreq('Y'), length=50) Both series have the same shape, ``(50, 12)``, but ``mseries`` is a series of one variable, with ``mseries.varshape == ()``, while ``aseries`` is a series of 12 variables, ``aseries.varshape == (12,)``, each variable corresponding to a month. >>> (mseries.shape, mseries.varshape) ((50, 12), ()) >>> (aseries.shape, aseries.varshape) ((50, 12), (12,)) Because ``aseries`` is basically a 2D array, we can easily compute annual and monthly means. Thus, monthly means over the whole 50 years can be calculated at once with the :meth:`~scikits.timeseries.mean` method, using ``axis=0`` as parameter. We can also compute the equivalent of 50 years of annual data using :meth:`~scikits.timeseries.mean` method, this time with ``axis=1``. >>> amean = aseries.mean(axis=1) >>> amean.shape = (50,) >>> mmean = aseries.mean(axis=0) >>> mmean.shape = (12,) Another example of multi-variable series would be one year of daily (256x256) raster map. This dataset can easily be represented as a (365,256,256)-array, and a corresponding series created with the following code:: >>> data = np.random.uniform(-1, +1, 365*256*256).reshape(365, 256, 256) >>> newseries = ts.time_series(data, start_date=ts.now('D')) Methods ======= Date information ---------------- The following methods access information about the :attr:`dates` attribute: .. only:: html =========================================== ======================================================================================== .. method:: TimeSeries.get_steps Returns the time steps between consecutive dates, in the same unit as the instance frequency. .. method:: TimeSeries.has_missing_dates Returns whether the instance has missing dates. .. method:: TimeSeries.has_duplicated_dates Returns whether the instance has duplicated dates. .. method:: TimeSeries.is_full Returns whether the instance has no missing dates. .. method:: TimeSeries.is_valid Returns whether the instance is valid (that there are no missing nor duplicated dates). .. method:: TimeSeries.is_chronological Returns whether the instance is sorted in chronological order. =========================================== ======================================================================================== .. only:: latex .. method:: TimeSeries.get_steps Returns the time steps between consecutive dates, in the same unit as the instance frequency. .. method:: TimeSeries.has_missing_dates Returns whether the instance has missing dates. .. method:: TimeSeries.has_duplicated_dates Returns whether the instance has duplicated dates. .. method:: TimeSeries.is_full Returns whether the instance has no missing dates. .. method:: TimeSeries.is_valid Returns whether the instance is valid (that there are no missing nor duplicated dates). .. method:: TimeSeries.is_chronological Returns whether the instance is sorted in chronological order. .. autosummary:: :toctree: generated/ TimeSeries.date_to_index TimeSeries.sort_chronologically Dates manipulation ------------------ .. autosummary:: :toctree: generated/ TimeSeries.adjust_endpoints TimeSeries.compressed TimeSeries.fill_missing_dates Shape manipulation ------------------ For reshape, resize, and transpose, the single tuple argument may be replaced with ``n`` integers which will be interpreted as an n-tuple. .. autosummary:: :toctree: generated/ TimeSeries.flatten TimeSeries.ravel TimeSeries.reshape TimeSeries.resize TimeSeries.split TimeSeries.squeeze TimeSeries.swapaxes TimeSeries.transpose TimeSeries.T Item selection and manipulation ------------------------------- .. autosummary:: :toctree: generated/ TimeSeries.argmax TimeSeries.argmin TimeSeries.argsort TimeSeries.choose TimeSeries.compress TimeSeries.diagonal TimeSeries.fill TimeSeries.filled TimeSeries.item TimeSeries.nonzero TimeSeries.put TimeSeries.repeat TimeSeries.searchsorted TimeSeries.sort TimeSeries.take TimeSeries.tshift Pickling and copy ----------------- .. autosummary:: :toctree: generated/ TimeSeries.copy TimeSeries.dump TimeSeries.dumps Calculations ------------ .. autosummary:: :toctree: generated/ TimeSeries.all TimeSeries.anom TimeSeries.any TimeSeries.clip TimeSeries.conj TimeSeries.conjugate TimeSeries.cumprod TimeSeries.cumsum TimeSeries.max TimeSeries.mean TimeSeries.min TimeSeries.pct TimeSeries.pct_log TimeSeries.pct_symmetric TimeSeries.prod TimeSeries.product TimeSeries.ptp TimeSeries.round TimeSeries.std TimeSeries.sum TimeSeries.trace TimeSeries.var .. Arithmetic and comparison operations ------------------------------------ .. index:: comparison, arithmetic, operation, operator Comparison operators: ~~~~~~~~~~~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.__lt__ TimeSeries.__le__ TimeSeries.__gt__ TimeSeries.__ge__ TimeSeries.__eq__ TimeSeries.__ne__ Truth value of an array (:func:`bool()`): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.__nonzero__ Arithmetic: ~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.__abs__ TimeSeries.__add__ TimeSeries.__radd__ TimeSeries.__sub__ TimeSeries.__rsub__ TimeSeries.__mul__ TimeSeries.__rmul__ TimeSeries.__div__ TimeSeries.__rdiv__ TimeSeries.__truediv__ TimeSeries.__rtruediv__ TimeSeries.__floordiv__ TimeSeries.__rfloordiv__ TimeSeries.__mod__ TimeSeries.__rmod__ TimeSeries.__divmod__ TimeSeries.__rdivmod__ TimeSeries.__pow__ TimeSeries.__rpow__ TimeSeries.__lshift__ TimeSeries.__rlshift__ TimeSeries.__rshift__ TimeSeries.__rrshift__ TimeSeries.__and__ TimeSeries.__rand__ TimeSeries.__or__ TimeSeries.__ror__ TimeSeries.__xor__ TimeSeries.__rxor__ Arithmetic, in-place: ~~~~~~~~~~~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.__iadd__ TimeSeries.__isub__ TimeSeries.__imul__ TimeSeries.__idiv__ TimeSeries.__itruediv__ TimeSeries.__ifloordiv__ TimeSeries.__imod__ TimeSeries.__ipow__ TimeSeries.__ilshift__ TimeSeries.__irshift__ TimeSeries.__iand__ TimeSeries.__ior__ TimeSeries.__ixor__ Representation -------------- .. autosummary:: :toctree: generated/ TimeSeries.__repr__ TimeSeries.__str__ TimeSeries.ids TimeSeries.iscontiguous Special methods --------------- For standard library functions: .. autosummary:: :toctree: generated/ TimeSeries.__copy__ TimeSeries.__deepcopy__ TimeSeries.__getstate__ TimeSeries.__reduce__ TimeSeries.__setstate__ Basic customization: .. autosummary:: :toctree: generated/ TimeSeries.__new__ TimeSeries.__array__ TimeSeries.__array_wrap__ Container customization: (see `Indexing <http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html>`_) .. autosummary:: :toctree: generated/ TimeSeries.__len__ TimeSeries.__getitem__ TimeSeries.__setitem__ TimeSeries.__delitem__ TimeSeries.__getslice__ TimeSeries.__setslice__ TimeSeries.__contains__ Methods inherited from :class:`~numpy.ma.MaskedArray` ----------------------------------------------------- Handling the mask ~~~~~~~~~~~~~~~~~ The following methods can be used to access information about the mask or to manipulate the mask. .. autosummary:: :toctree: generated/ TimeSeries.__setmask__ TimeSeries.harden_mask TimeSeries.soften_mask TimeSeries.unshare_mask TimeSeries.shrink_mask Handling the :attr:`fill_value` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.get_fill_value TimeSeries.set_fill_value Counting the missing elements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. autosummary:: :toctree: generated/ TimeSeries.count