| 105 | |
| 106 | |
| 107 | class _CFTimeFrequencyInferer: # (pd.tseries.frequencies._FrequencyInferer): |
| 108 | def __init__(self, index): |
| 109 | self.index = index |
| 110 | self.values = index.asi8 |
| 111 | |
| 112 | if len(index) < 3: |
| 113 | raise ValueError("Need at least 3 dates to infer frequency") |
| 114 | |
| 115 | self.is_monotonic = ( |
| 116 | self.index.is_monotonic_decreasing or self.index.is_monotonic_increasing |
| 117 | ) |
| 118 | |
| 119 | self._deltas = None |
| 120 | self._year_deltas = None |
| 121 | self._month_deltas = None |
| 122 | |
| 123 | def get_freq(self): |
| 124 | """Find the appropriate frequency string to describe the inferred frequency of self.index |
| 125 | |
| 126 | Adapted from `pandas.tsseries.frequencies._FrequencyInferer.get_freq` for CFTimeIndexes. |
| 127 | |
| 128 | Returns |
| 129 | ------- |
| 130 | str or None |
| 131 | """ |
| 132 | if not self.is_monotonic or not self.index.is_unique: |
| 133 | return None |
| 134 | |
| 135 | delta = self.deltas[0] # Smallest delta |
| 136 | if _is_multiple(delta, _ONE_DAY): |
| 137 | return self._infer_daily_rule() |
| 138 | # There is no possible intraday frequency with a non-unique delta |
| 139 | # Different from pandas: we don't need to manage DST and business offsets in cftime |
| 140 | elif len(self.deltas) != 1: |
| 141 | return None |
| 142 | |
| 143 | if _is_multiple(delta, _ONE_HOUR): |
| 144 | return _maybe_add_count("h", delta / _ONE_HOUR) |
| 145 | elif _is_multiple(delta, _ONE_MINUTE): |
| 146 | return _maybe_add_count("min", delta / _ONE_MINUTE) |
| 147 | elif _is_multiple(delta, _ONE_SECOND): |
| 148 | return _maybe_add_count("s", delta / _ONE_SECOND) |
| 149 | elif _is_multiple(delta, _ONE_MILLI): |
| 150 | return _maybe_add_count("ms", delta / _ONE_MILLI) |
| 151 | else: |
| 152 | return _maybe_add_count("us", delta / _ONE_MICRO) |
| 153 | |
| 154 | def _infer_daily_rule(self): |
| 155 | annual_rule = self._get_annual_rule() |
| 156 | if annual_rule: |
| 157 | nyears = self.year_deltas[0] |
| 158 | month = _MONTH_ABBREVIATIONS[self.index[0].month] |
| 159 | alias = f"{annual_rule}-{month}" |
| 160 | return _maybe_add_count(alias, nyears) |
| 161 | |
| 162 | quartely_rule = self._get_quartely_rule() |
| 163 | if quartely_rule: |
| 164 | nquarters = self.month_deltas[0] / 3 |
no outgoing calls
no test coverage detected
searching dependent graphs…