def _test(ax): xlim = ax.get_xlim() ax.set_xlim(xlim[0] - 5, xlim[1] + 10) ax.get_figure().canvas.draw() result = ax.get_xlim() self.assertEqual(result[0], xlim[0] - 5) self.assertEqual(result[1], xlim[1] + 10) # string expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq)) ax.set_xlim('1/1/2000', '4/1/2000') ax.get_figure().canvas.draw() result = ax.get_xlim() self.assertEqual(int(result[0]), expected[0].ordinal) self.assertEqual(int(result[1]), expected[1].ordinal) # datetim expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq)) ax.set_xlim(datetime(2000, 1, 1), datetime(2000, 4, 1)) ax.get_figure().canvas.draw() result = ax.get_xlim() self.assertEqual(int(result[0]), expected[0].ordinal) self.assertEqual(int(result[1]), expected[1].ordinal) fig = ax.get_figure() plt.close(fig)
def _test(ax): xlim = ax.get_xlim() ax.set_xlim(xlim[0] - 5, xlim[1] + 10) ax.get_figure().canvas.draw() result = ax.get_xlim() assert result[0] == xlim[0] - 5 assert result[1] == xlim[1] + 10 # string expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq)) ax.set_xlim('1/1/2000', '4/1/2000') ax.get_figure().canvas.draw() result = ax.get_xlim() assert int(result[0]) == expected[0].ordinal assert int(result[1]) == expected[1].ordinal # datetim expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq)) ax.set_xlim(datetime(2000, 1, 1), datetime(2000, 4, 1)) ax.get_figure().canvas.draw() result = ax.get_xlim() assert int(result[0]) == expected[0].ordinal assert int(result[1]) == expected[1].ordinal fig = ax.get_figure() plt.close(fig)
def test_get_datevalue(self): from pandas.plotting._converter import get_datevalue assert get_datevalue(None, 'D') is None assert get_datevalue(1987, 'A') == 1987 assert (get_datevalue(Period(1987, 'A'), 'M') == Period('1987-12', 'M').ordinal) assert (get_datevalue('1/1/1987', 'D') == Period('1987-1-1', 'D').ordinal)
def test_get_datevalue(self): from pandas.plotting._converter import get_datevalue self.assertIsNone(get_datevalue(None, 'D')) self.assertEqual(get_datevalue(1987, 'A'), 1987) self.assertEqual(get_datevalue(Period(1987, 'A'), 'M'), Period('1987-12', 'M').ordinal) self.assertEqual(get_datevalue('1/1/1987', 'D'), Period('1987-1-1', 'D').ordinal)
def test_get_period_range_edges(self, first, last, freq, exp_first, exp_last): first = Period(first) last = Period(last) exp_first = Period(exp_first, freq=freq) exp_last = Period(exp_last, freq=freq) freq = pd.tseries.frequencies.to_offset(freq) result = _get_period_range_edges(first, last, freq) expected = (exp_first, exp_last) assert result == expected
def __call__(self, x, pos: int = 0) -> str: if self.formatdict is None: return "" else: fmt = self.formatdict.pop(x, "") if isinstance(fmt, np.bytes_): fmt = fmt.decode("utf-8") period = Period(ordinal=int(x), freq=self.freq) assert isinstance(period, Period) return period.strftime(fmt)
def test_resample_dup_index(): # GH 4812 # dup columns with resample raising df = DataFrame(np.random.randn(4, 12), index=[2000, 2000, 2000, 2000], columns=[Period(year=2000, month=i + 1, freq='M') for i in range(12)]) df.iloc[3, :] = np.nan result = df.resample('Q', axis=1).mean() expected = df.groupby(lambda x: int((x.month - 1) / 3), axis=1).mean() expected.columns = [ Period(year=2000, quarter=i + 1, freq='Q') for i in range(4)] assert_frame_equal(result, expected)
def test_resample_basic(self): # GH3609 s = Series(range(100), index=date_range( '20130101', freq='s', periods=100, name='idx'), dtype='float') s[10:30] = np.nan index = PeriodIndex([ Period('2013-01-01 00:00', 'T'), Period('2013-01-01 00:01', 'T')], name='idx') expected = Series([34.5, 79.5], index=index) result = s.to_period().resample('T', kind='period').mean() assert_series_equal(result, expected) result2 = s.resample('T', kind='period').mean() assert_series_equal(result2, expected)
def _use_dynamic_x(ax, data): freq = _get_index_freq(data) ax_freq = _get_ax_freq(ax) if freq is None: # convert irregular if axes has freq info freq = ax_freq else: # do not use tsplot if irregular was plotted first if (ax_freq is None) and (len(ax.get_lines()) > 0): return False if freq is None: return False if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) if freq is None: return False # hack this for 0.10.1, creating more technical debt...sigh if isinstance(data.index, DatetimeIndex): base = frequencies.get_freq(freq) x = data.index if (base <= frequencies.FreqGroup.FR_DAY): return x[:1].is_normalized return Period(x[0], freq).to_timestamp(tz=x.tz) == x[0] return True
def __call__(self, x, pos=0): if self.formatdict is None: return "" else: fmt = self.formatdict.pop(x, "") return Period(ordinal=int(x), freq=self.freq).strftime(fmt)
def test_period_index_construction_from_strings(klass): # https://github.com/pandas-dev/pandas/issues/26109 strings = ["2020Q1", "2020Q2"] * 2 data = klass(strings) result = PeriodIndex(data, freq="Q") expected = PeriodIndex([Period(s) for s in strings]) tm.assert_index_equal(result, expected)
def test_finder_monthly_long(self): rng = period_range('1988Q1', periods=24 * 12, freq='M') ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] xp = Period('1989Q1', 'M').ordinal self.assertEqual(rs, xp)
def test_resample_basic(self): # GH3609 s = Series( range(100), index=date_range("20130101", freq="s", periods=100, name="idx"), dtype="float", ) s[10:30] = np.nan index = PeriodIndex( [Period("2013-01-01 00:00", "T"), Period("2013-01-01 00:01", "T")], name="idx", ) expected = Series([34.5, 79.5], index=index) result = s.to_period().resample("T", kind="period").mean() tm.assert_series_equal(result, expected) result2 = s.resample("T", kind="period").mean() tm.assert_series_equal(result2, expected)
def __call__(self, x, pos=0): _check_implicitly_registered() if self.formatdict is None: return '' else: fmt = self.formatdict.pop(x, '') return Period(ordinal=int(x), freq=self.freq).strftime(fmt)
def test_finder_hourly(self): nhours = 23 rng = date_range('1/1/1999', freq='H', periods=nhours) ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] xp = Period('1/1/1999', freq='H').ordinal self.assertEqual(rs, xp)
def __call__(self, x, pos=0): if self.formatdict is None: return "" else: fmt = self.formatdict.pop(x, "") if isinstance(fmt, np.bytes_): fmt = fmt.decode("utf-8") return Period(ordinal=int(x), freq=self.freq).strftime(fmt)
def test_finder_minutely(self): nminutes = 50 * 24 * 60 rng = date_range('1/1/1999', freq='Min', periods=nminutes) ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] xp = Period('1/1/1999', freq='Min').ordinal self.assertEqual(rs, xp)
def test_finder_annual(self): import matplotlib.pyplot as plt xp = [1987, 1988, 1990, 1990, 1995, 2020, 2070, 2170] for i, nyears in enumerate([5, 10, 19, 49, 99, 199, 599, 1001]): rng = period_range('1987', periods=nyears, freq='A') ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] self.assertEqual(rs, Period(xp[i], freq='A').ordinal) plt.close(ax.get_figure())
def get_datevalue(date, freq): if isinstance(date, Period): return date.asfreq(freq).ordinal elif isinstance(date, (str, datetime, pydt.date, pydt.time, np.datetime64)): return Period(date, freq).ordinal elif (is_integer(date) or is_float(date) or (isinstance(date, (np.ndarray, Index)) and (date.size == 1))): return date elif date is None: return None raise ValueError(f"Unrecognizable date '{date}'")
def get_datevalue(date, freq): if isinstance(date, Period): return date.asfreq(freq).ordinal elif isinstance(date, (compat.string_types, datetime, pydt.date, pydt.time)): return Period(date, freq).ordinal elif (is_integer(date) or is_float(date) or (isinstance(date, (np.ndarray, Index)) and (date.size == 1))): return date elif date is None: return None raise ValueError("Unrecognizable date '%s'" % date)
def test_finder_quarterly(self): import matplotlib.pyplot as plt xp = Period('1988Q1').ordinal yrs = [3.5, 11] for n in yrs: rng = period_range('1987Q2', periods=int(n * 4), freq='Q') ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] assert rs == xp (vmin, vmax) = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs = xaxis.get_majorticklocs()[0] assert xp == rs plt.close(ax.get_figure())
def test_finder_daily(self): import matplotlib.pyplot as plt xp = Period('1999-1-1', freq='B').ordinal day_lst = [10, 40, 252, 400, 950, 2750, 10000] for n in day_lst: rng = bdate_range('1999-1-1', periods=n) ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] self.assertEqual(xp, rs) vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs = xaxis.get_majorticklocs()[0] self.assertEqual(xp, rs) plt.close(ax.get_figure())
def test_finder_monthly(self): import matplotlib.pyplot as plt xp = Period('Jan 1988').ordinal yrs = [1.15, 2.5, 4, 11] for n in yrs: rng = period_range('1987Q2', periods=int(n * 12), freq='M') ser = Series(np.random.randn(len(rng)), rng) ax = ser.plot() xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] self.assertEqual(rs, xp) vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs = xaxis.get_majorticklocs()[0] self.assertEqual(xp, rs) plt.close(ax.get_figure())
def format_dateaxis(subplot, freq, index): """ Pretty-formats the date axis (x-axis). Major and minor ticks are automatically set for the frequency of the current underlying series. As the dynamic mode is activated by default, changing the limits of the x axis will intelligently change the positions of the ticks. """ # handle index specific formatting # Note: DatetimeIndex does not use this # interface. DatetimeIndex uses matplotlib.date directly if isinstance(index, PeriodIndex): majlocator = TimeSeries_DateLocator(freq, dynamic_mode=True, minor_locator=False, plot_obj=subplot) minlocator = TimeSeries_DateLocator(freq, dynamic_mode=True, minor_locator=True, plot_obj=subplot) subplot.xaxis.set_major_locator(majlocator) subplot.xaxis.set_minor_locator(minlocator) majformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True, minor_locator=False, plot_obj=subplot) minformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True, minor_locator=True, plot_obj=subplot) subplot.xaxis.set_major_formatter(majformatter) subplot.xaxis.set_minor_formatter(minformatter) # x and y coord info subplot.format_coord = lambda t, y: ("t = {0} y = {1:8f}".format( Period(ordinal=int(t), freq=freq), y)) elif isinstance(index, TimedeltaIndex): subplot.xaxis.set_major_formatter(TimeSeries_TimedeltaFormatter()) else: raise TypeError('index type not supported') pylab.draw_if_interactive()
def test_take_fill_valid(self, arr1d): arr = arr1d dti = self.index_cls(arr1d) now = Timestamp.now().tz_localize(dti.tz) result = arr.take([-1, 1], allow_fill=True, fill_value=now) assert result[0] == now msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got" with pytest.raises(TypeError, match=msg): # fill_value Timedelta invalid arr.take([-1, 1], allow_fill=True, fill_value=now - now) with pytest.raises(TypeError, match=msg): # fill_value Period invalid arr.take([-1, 1], allow_fill=True, fill_value=Period("2014Q1")) tz = None if dti.tz is not None else "US/Eastern" now = Timestamp.now().tz_localize(tz) msg = "Cannot compare tz-naive and tz-aware datetime-like objects" with pytest.raises(TypeError, match=msg): # Timestamp with mismatched tz-awareness arr.take([-1, 1], allow_fill=True, fill_value=now) value = pd.NaT.value msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got" with pytest.raises(TypeError, match=msg): # require NaT, not iNaT, as it could be confused with an integer arr.take([-1, 1], allow_fill=True, fill_value=value) value = np.timedelta64("NaT", "ns") with pytest.raises(TypeError, match=msg): # require appropriate-dtype if we have a NA value arr.take([-1, 1], allow_fill=True, fill_value=value) if arr.tz is not None: # GH#37356 # Assuming here that arr1d fixture does not include Australia/Melbourne value = Timestamp.now().tz_localize("Australia/Melbourne") msg = "Timezones don't match. .* != 'Australia/Melbourne'" with pytest.raises(ValueError, match=msg): # require tz match, not just tzawareness match arr.take([-1, 1], allow_fill=True, fill_value=value)
def test_corner_cases(simple_period_range_series, simple_date_range_series): # miscellaneous test coverage rng = date_range("1/1/2000", periods=12, freq="t") ts = Series(np.random.randn(len(rng)), index=rng) result = ts.resample("5t", closed="right", label="left").mean() ex_index = date_range("1999-12-31 23:55", periods=4, freq="5t") tm.assert_index_equal(result.index, ex_index) len0pts = simple_period_range_series("2007-01", "2010-05", freq="M")[:0] # it works result = len0pts.resample("A-DEC").mean() assert len(result) == 0 # resample to periods ts = simple_date_range_series("2000-04-28", "2000-04-30 11:00", freq="h") result = ts.resample("M", kind="period").mean() assert len(result) == 1 assert result.index[0] == Period("2000-04", freq="M")
def test_corner_cases(simple_period_range_series, simple_date_range_series): # miscellaneous test coverage rng = date_range('1/1/2000', periods=12, freq='t') ts = Series(np.random.randn(len(rng)), index=rng) result = ts.resample('5t', closed='right', label='left').mean() ex_index = date_range('1999-12-31 23:55', periods=4, freq='5t') tm.assert_index_equal(result.index, ex_index) len0pts = simple_period_range_series('2007-01', '2010-05', freq='M')[:0] # it works result = len0pts.resample('A-DEC').mean() assert len(result) == 0 # resample to periods ts = simple_date_range_series('2000-04-28', '2000-04-30 11:00', freq='h') result = ts.resample('M', kind='period').mean() assert len(result) == 1 assert result.index[0] == Period('2000-04', freq='M')
def _daily_finder(vmin, vmax, freq): periodsperday = -1 if freq >= FreqGroup.FR_HR: if freq == FreqGroup.FR_NS: periodsperday = 24 * 60 * 60 * 1000000000 elif freq == FreqGroup.FR_US: periodsperday = 24 * 60 * 60 * 1000000 elif freq == FreqGroup.FR_MS: periodsperday = 24 * 60 * 60 * 1000 elif freq == FreqGroup.FR_SEC: periodsperday = 24 * 60 * 60 elif freq == FreqGroup.FR_MIN: periodsperday = 24 * 60 elif freq == FreqGroup.FR_HR: periodsperday = 24 else: # pragma: no cover raise ValueError(f"unexpected frequency: {freq}") periodsperyear = 365 * periodsperday periodspermonth = 28 * periodsperday elif freq == FreqGroup.FR_BUS: periodsperyear = 261 periodspermonth = 19 elif freq == FreqGroup.FR_DAY: periodsperyear = 365 periodspermonth = 28 elif resolution.get_freq_group(freq) == FreqGroup.FR_WK: periodsperyear = 52 periodspermonth = 3 else: # pragma: no cover raise ValueError("unexpected frequency") # save this for later usage vmin_orig = vmin (vmin, vmax) = ( Period(ordinal=int(vmin), freq=freq), Period(ordinal=int(vmax), freq=freq), ) span = vmax.ordinal - vmin.ordinal + 1 dates_ = period_range(start=vmin, end=vmax, freq=freq) # Initialize the output info = np.zeros(span, dtype=[("val", np.int64), ("maj", bool), ("min", bool), ("fmt", "|S20")]) info["val"][:] = dates_.asi8 info["fmt"][:] = "" info["maj"][[0, -1]] = True # .. and set some shortcuts info_maj = info["maj"] info_min = info["min"] info_fmt = info["fmt"] def first_label(label_flags): if (label_flags[0] == 0) and (label_flags.size > 1) and ((vmin_orig % 1) > 0.0): return label_flags[1] else: return label_flags[0] # Case 1. Less than a month if span <= periodspermonth: day_start = period_break(dates_, "day") month_start = period_break(dates_, "month") def _hour_finder(label_interval, force_year_start): _hour = dates_.hour _prev_hour = (dates_ - 1 * dates_.freq).hour hour_start = (_hour - _prev_hour) != 0 info_maj[day_start] = True info_min[hour_start & (_hour % label_interval == 0)] = True year_start = period_break(dates_, "year") info_fmt[hour_start & (_hour % label_interval == 0)] = "%H:%M" info_fmt[day_start] = "%H:%M\n%d-%b" info_fmt[year_start] = "%H:%M\n%d-%b\n%Y" if force_year_start and not has_level_label(year_start, vmin_orig): info_fmt[first_label(day_start)] = "%H:%M\n%d-%b\n%Y" def _minute_finder(label_interval): hour_start = period_break(dates_, "hour") _minute = dates_.minute _prev_minute = (dates_ - 1 * dates_.freq).minute minute_start = (_minute - _prev_minute) != 0 info_maj[hour_start] = True info_min[minute_start & (_minute % label_interval == 0)] = True year_start = period_break(dates_, "year") info_fmt = info["fmt"] info_fmt[minute_start & (_minute % label_interval == 0)] = "%H:%M" info_fmt[day_start] = "%H:%M\n%d-%b" info_fmt[year_start] = "%H:%M\n%d-%b\n%Y" def _second_finder(label_interval): minute_start = period_break(dates_, "minute") _second = dates_.second _prev_second = (dates_ - 1 * dates_.freq).second second_start = (_second - _prev_second) != 0 info["maj"][minute_start] = True info["min"][second_start & (_second % label_interval == 0)] = True year_start = period_break(dates_, "year") info_fmt = info["fmt"] info_fmt[second_start & (_second % label_interval == 0)] = "%H:%M:%S" info_fmt[day_start] = "%H:%M:%S\n%d-%b" info_fmt[year_start] = "%H:%M:%S\n%d-%b\n%Y" if span < periodsperday / 12000.0: _second_finder(1) elif span < periodsperday / 6000.0: _second_finder(2) elif span < periodsperday / 2400.0: _second_finder(5) elif span < periodsperday / 1200.0: _second_finder(10) elif span < periodsperday / 800.0: _second_finder(15) elif span < periodsperday / 400.0: _second_finder(30) elif span < periodsperday / 150.0: _minute_finder(1) elif span < periodsperday / 70.0: _minute_finder(2) elif span < periodsperday / 24.0: _minute_finder(5) elif span < periodsperday / 12.0: _minute_finder(15) elif span < periodsperday / 6.0: _minute_finder(30) elif span < periodsperday / 2.5: _hour_finder(1, False) elif span < periodsperday / 1.5: _hour_finder(2, False) elif span < periodsperday * 1.25: _hour_finder(3, False) elif span < periodsperday * 2.5: _hour_finder(6, True) elif span < periodsperday * 4: _hour_finder(12, True) else: info_maj[month_start] = True info_min[day_start] = True year_start = period_break(dates_, "year") info_fmt = info["fmt"] info_fmt[day_start] = "%d" info_fmt[month_start] = "%d\n%b" info_fmt[year_start] = "%d\n%b\n%Y" if not has_level_label(year_start, vmin_orig): if not has_level_label(month_start, vmin_orig): info_fmt[first_label(day_start)] = "%d\n%b\n%Y" else: info_fmt[first_label(month_start)] = "%d\n%b\n%Y" # Case 2. Less than three months elif span <= periodsperyear // 4: month_start = period_break(dates_, "month") info_maj[month_start] = True if freq < FreqGroup.FR_HR: info["min"] = True else: day_start = period_break(dates_, "day") info["min"][day_start] = True week_start = period_break(dates_, "week") year_start = period_break(dates_, "year") info_fmt[week_start] = "%d" info_fmt[month_start] = "\n\n%b" info_fmt[year_start] = "\n\n%b\n%Y" if not has_level_label(year_start, vmin_orig): if not has_level_label(month_start, vmin_orig): info_fmt[first_label(week_start)] = "\n\n%b\n%Y" else: info_fmt[first_label(month_start)] = "\n\n%b\n%Y" # Case 3. Less than 14 months ............... elif span <= 1.15 * periodsperyear: year_start = period_break(dates_, "year") month_start = period_break(dates_, "month") week_start = period_break(dates_, "week") info_maj[month_start] = True info_min[week_start] = True info_min[year_start] = False info_min[month_start] = False info_fmt[month_start] = "%b" info_fmt[year_start] = "%b\n%Y" if not has_level_label(year_start, vmin_orig): info_fmt[first_label(month_start)] = "%b\n%Y" # Case 4. Less than 2.5 years ............... elif span <= 2.5 * periodsperyear: year_start = period_break(dates_, "year") quarter_start = period_break(dates_, "quarter") month_start = period_break(dates_, "month") info_maj[quarter_start] = True info_min[month_start] = True info_fmt[quarter_start] = "%b" info_fmt[year_start] = "%b\n%Y" # Case 4. Less than 4 years ................. elif span <= 4 * periodsperyear: year_start = period_break(dates_, "year") month_start = period_break(dates_, "month") info_maj[year_start] = True info_min[month_start] = True info_min[year_start] = False month_break = dates_[month_start].month jan_or_jul = month_start[(month_break == 1) | (month_break == 7)] info_fmt[jan_or_jul] = "%b" info_fmt[year_start] = "%b\n%Y" # Case 5. Less than 11 years ................ elif span <= 11 * periodsperyear: year_start = period_break(dates_, "year") quarter_start = period_break(dates_, "quarter") info_maj[year_start] = True info_min[quarter_start] = True info_min[year_start] = False info_fmt[year_start] = "%Y" # Case 6. More than 12 years ................ else: year_start = period_break(dates_, "year") year_break = dates_[year_start].year nyears = span / periodsperyear (min_anndef, maj_anndef) = _get_default_annual_spacing(nyears) major_idx = year_start[(year_break % maj_anndef == 0)] info_maj[major_idx] = True minor_idx = year_start[(year_break % min_anndef == 0)] info_min[minor_idx] = True info_fmt[major_idx] = "%Y" return info
def _format_coord(freq, t, y): return "t = {0} y = {1:8f}".format(Period(ordinal=int(t), freq=freq), y)
def _daily_finder(vmin, vmax, freq): periodsperday = -1 if freq >= FreqGroup.FR_HR: if freq == FreqGroup.FR_NS: periodsperday = 24 * 60 * 60 * 1000000000 elif freq == FreqGroup.FR_US: periodsperday = 24 * 60 * 60 * 1000000 elif freq == FreqGroup.FR_MS: periodsperday = 24 * 60 * 60 * 1000 elif freq == FreqGroup.FR_SEC: periodsperday = 24 * 60 * 60 elif freq == FreqGroup.FR_MIN: periodsperday = 24 * 60 elif freq == FreqGroup.FR_HR: periodsperday = 24 else: # pragma: no cover raise ValueError("unexpected frequency: %s" % freq) periodsperyear = 365 * periodsperday periodspermonth = 28 * periodsperday elif freq == FreqGroup.FR_BUS: periodsperyear = 261 periodspermonth = 19 elif freq == FreqGroup.FR_DAY: periodsperyear = 365 periodspermonth = 28 elif frequencies.get_freq_group(freq) == FreqGroup.FR_WK: periodsperyear = 52 periodspermonth = 3 else: # pragma: no cover raise ValueError("unexpected frequency") # save this for later usage vmin_orig = vmin (vmin, vmax) = (Period(ordinal=int(vmin), freq=freq), Period(ordinal=int(vmax), freq=freq)) span = vmax.ordinal - vmin.ordinal + 1 dates_ = PeriodIndex(start=vmin, end=vmax, freq=freq) # Initialize the output info = np.zeros(span, dtype=[('val', np.int64), ('maj', bool), ('min', bool), ('fmt', '|S20')]) info['val'][:] = dates_._values info['fmt'][:] = '' info['maj'][[0, -1]] = True # .. and set some shortcuts info_maj = info['maj'] info_min = info['min'] info_fmt = info['fmt'] def first_label(label_flags): if (label_flags[0] == 0) and (label_flags.size > 1) and \ ((vmin_orig % 1) > 0.0): return label_flags[1] else: return label_flags[0] # Case 1. Less than a month if span <= periodspermonth: day_start = period_break(dates_, 'day') month_start = period_break(dates_, 'month') def _hour_finder(label_interval, force_year_start): _hour = dates_.hour _prev_hour = (dates_ - 1).hour hour_start = (_hour - _prev_hour) != 0 info_maj[day_start] = True info_min[hour_start & (_hour % label_interval == 0)] = True year_start = period_break(dates_, 'year') info_fmt[hour_start & (_hour % label_interval == 0)] = '%H:%M' info_fmt[day_start] = '%H:%M\n%d-%b' info_fmt[year_start] = '%H:%M\n%d-%b\n%Y' if force_year_start and not has_level_label(year_start, vmin_orig): info_fmt[first_label(day_start)] = '%H:%M\n%d-%b\n%Y' def _minute_finder(label_interval): hour_start = period_break(dates_, 'hour') _minute = dates_.minute _prev_minute = (dates_ - 1).minute minute_start = (_minute - _prev_minute) != 0 info_maj[hour_start] = True info_min[minute_start & (_minute % label_interval == 0)] = True year_start = period_break(dates_, 'year') info_fmt = info['fmt'] info_fmt[minute_start & (_minute % label_interval == 0)] = '%H:%M' info_fmt[day_start] = '%H:%M\n%d-%b' info_fmt[year_start] = '%H:%M\n%d-%b\n%Y' def _second_finder(label_interval): minute_start = period_break(dates_, 'minute') _second = dates_.second _prev_second = (dates_ - 1).second second_start = (_second - _prev_second) != 0 info['maj'][minute_start] = True info['min'][second_start & (_second % label_interval == 0)] = True year_start = period_break(dates_, 'year') info_fmt = info['fmt'] info_fmt[second_start & (_second % label_interval == 0)] = '%H:%M:%S' info_fmt[day_start] = '%H:%M:%S\n%d-%b' info_fmt[year_start] = '%H:%M:%S\n%d-%b\n%Y' if span < periodsperday / 12000.0: _second_finder(1) elif span < periodsperday / 6000.0: _second_finder(2) elif span < periodsperday / 2400.0: _second_finder(5) elif span < periodsperday / 1200.0: _second_finder(10) elif span < periodsperday / 800.0: _second_finder(15) elif span < periodsperday / 400.0: _second_finder(30) elif span < periodsperday / 150.0: _minute_finder(1) elif span < periodsperday / 70.0: _minute_finder(2) elif span < periodsperday / 24.0: _minute_finder(5) elif span < periodsperday / 12.0: _minute_finder(15) elif span < periodsperday / 6.0: _minute_finder(30) elif span < periodsperday / 2.5: _hour_finder(1, False) elif span < periodsperday / 1.5: _hour_finder(2, False) elif span < periodsperday * 1.25: _hour_finder(3, False) elif span < periodsperday * 2.5: _hour_finder(6, True) elif span < periodsperday * 4: _hour_finder(12, True) else: info_maj[month_start] = True info_min[day_start] = True year_start = period_break(dates_, 'year') info_fmt = info['fmt'] info_fmt[day_start] = '%d' info_fmt[month_start] = '%d\n%b' info_fmt[year_start] = '%d\n%b\n%Y' if not has_level_label(year_start, vmin_orig): if not has_level_label(month_start, vmin_orig): info_fmt[first_label(day_start)] = '%d\n%b\n%Y' else: info_fmt[first_label(month_start)] = '%d\n%b\n%Y' # Case 2. Less than three months elif span <= periodsperyear // 4: month_start = period_break(dates_, 'month') info_maj[month_start] = True if freq < FreqGroup.FR_HR: info['min'] = True else: day_start = period_break(dates_, 'day') info['min'][day_start] = True week_start = period_break(dates_, 'week') year_start = period_break(dates_, 'year') info_fmt[week_start] = '%d' info_fmt[month_start] = '\n\n%b' info_fmt[year_start] = '\n\n%b\n%Y' if not has_level_label(year_start, vmin_orig): if not has_level_label(month_start, vmin_orig): info_fmt[first_label(week_start)] = '\n\n%b\n%Y' else: info_fmt[first_label(month_start)] = '\n\n%b\n%Y' # Case 3. Less than 14 months ............... elif span <= 1.15 * periodsperyear: year_start = period_break(dates_, 'year') month_start = period_break(dates_, 'month') week_start = period_break(dates_, 'week') info_maj[month_start] = True info_min[week_start] = True info_min[year_start] = False info_min[month_start] = False info_fmt[month_start] = '%b' info_fmt[year_start] = '%b\n%Y' if not has_level_label(year_start, vmin_orig): info_fmt[first_label(month_start)] = '%b\n%Y' # Case 4. Less than 2.5 years ............... elif span <= 2.5 * periodsperyear: year_start = period_break(dates_, 'year') quarter_start = period_break(dates_, 'quarter') month_start = period_break(dates_, 'month') info_maj[quarter_start] = True info_min[month_start] = True info_fmt[quarter_start] = '%b' info_fmt[year_start] = '%b\n%Y' # Case 4. Less than 4 years ................. elif span <= 4 * periodsperyear: year_start = period_break(dates_, 'year') month_start = period_break(dates_, 'month') info_maj[year_start] = True info_min[month_start] = True info_min[year_start] = False month_break = dates_[month_start].month jan_or_jul = month_start[(month_break == 1) | (month_break == 7)] info_fmt[jan_or_jul] = '%b' info_fmt[year_start] = '%b\n%Y' # Case 5. Less than 11 years ................ elif span <= 11 * periodsperyear: year_start = period_break(dates_, 'year') quarter_start = period_break(dates_, 'quarter') info_maj[year_start] = True info_min[quarter_start] = True info_min[year_start] = False info_fmt[year_start] = '%Y' # Case 6. More than 12 years ................ else: year_start = period_break(dates_, 'year') year_break = dates_[year_start].year nyears = span / periodsperyear (min_anndef, maj_anndef) = _get_default_annual_spacing(nyears) major_idx = year_start[(year_break % maj_anndef == 0)] info_maj[major_idx] = True minor_idx = year_start[(year_break % min_anndef == 0)] info_min[minor_idx] = True info_fmt[major_idx] = '%Y' return info