| | 99 | |
| | 100 | |
| | 101 | |
| | 102 | def convert_to_annual(series): |
| | 103 | """ |
| | 104 | Group a series by years, taking leap years into account. |
| | 105 | |
| | 106 | The output has as many rows as distinct years in the original series, |
| | 107 | and as many columns as the length of a leap year in the units corresponding |
| | 108 | to the original frequency (366 for daily frequency, 366*24 for hourly...). |
| | 109 | The fist column of the output corresponds to Jan. 1st, 00:00:00, |
| | 110 | while the last column corresponds to Dec, 31st, 23:59:59. |
| | 111 | Entries corresponding to Feb. 29th are masked for non-leap years. |
| | 112 | |
| | 113 | For example, if the initial series has a daily frequency, the 59th column |
| | 114 | of the output always corresponds to Feb. 28th, the 61st column to Mar. 1st, |
| | 115 | and the 60th column is masked for non-leap years. |
| | 116 | With a hourly initial frequency, the (59*24)th column of the output always |
| | 117 | correspond to Feb. 28th 23:00, the (61*24)th column to Mar. 1st, 00:00, and |
| | 118 | the 24 columns between (59*24) and (61*24) are masked. |
| | 119 | |
| | 120 | If the original frequency is less than daily, the output is equivalent to |
| | 121 | ``series.convert('A', func=None)``. |
| | 122 | |
| | 123 | |
| | 124 | Parameters |
| | 125 | ---------- |
| | 126 | series : TimeSeries |
| | 127 | A valid :class:`~scikits.timeseries.TimeSeries` object. |
| | 128 | |
| | 129 | Returns |
| | 130 | ------- |
| | 131 | aseries : TimeSeries |
| | 132 | A 2D :class:`~scikits.timeseries.TimeSeries` object with annual ('A') |
| | 133 | frequency. |
| | 134 | |
| | 135 | """ |
| | 136 | dates = series.dates |
| | 137 | if dates.freq < _c.FR_DAY: |
| | 138 | return series.convert('A') |
| | 139 | idx0228 = dates.date_to_index(Date(dates.freq, |
| | 140 | year=dates[0].year, month=2, day=28, |
| | 141 | hour=00, minute=00, second=00)) |
| | 142 | idx0301 = dates.date_to_index(Date(dates.freq, |
| | 143 | year=dates[0].year, month=3, day=1, |
| | 144 | hour=00, minute=00, second=00)) |
| | 145 | aseries = series.convert('A') |
| | 146 | leapcondition = isleapyear(aseries.dates.years) |
| | 147 | leapidx = np.arange(len(aseries), dtype=int)[~leapcondition] |
| | 148 | aseries[leapidx, idx0301:] = aseries[leapidx, idx0228:idx0228-idx0301] |
| | 149 | aseries[leapidx, idx0228:idx0301] = ma.masked |
| | 150 | return aseries |
| | 151 | |
| | 152 | |