lilio.calendar_shorthands

Shorthands for calendars, to make generating commonly used calendars a one-liner.

Module Contents

class lilio.calendar_shorthands.Calendar(anchor: str, allow_overlap: bool = False, mapping: None | _MappingYears | _MappingData | _MappingDataGreedy = None, intervals: None | list[Interval] = None)[source]

Build a calendar from scratch with basic construction elements.

Instantiate a basic container for building calendar using basic blocks.

This is a highly flexible calendar which allows the user to build their own calendar with the basic building blocks of target and precursor periods.

Users have the freedom to create calendar with customized intervals, gap between intervals, and even overlapped intervals. They need to manage the calendar themselves.

Some shorthand calendars, such as a daily_calendar, weekly_calendar and monthly_calendar are available in lilio.calendar_shorthands. These can be used to easily construct basic calendars with only a few parameters, but do not have the flexibility that this calendar builder module provides.

Parameters:
  • anchor –

    String denoting the anchor date. The following inputs are valid: - β€œMM-DD” for a month and day. E.g. β€œ12-31”. - β€œMM” for only a month, e.g. β€œ4” for March. - English names and abbreviations of months. E.g. β€œDecember” or

    ”jan”.

    • ”Www” for a week number, e.g. β€œW05” for the fifth week of the

      year.

    • ”Www-D” for a week number plus day of week. E.g. β€œW01-4” for the

      first thursday of the year.

  • allow_overlap – If overlapping intervals between years is allowed or not. Default behaviour is False, which means that anchor years will be skipped to avoid data being shared between anchor years.

  • mapping – Calendar mapping. Input in the form: (β€œyears”, 2000, 2020) or (β€œdata”, pd.Timestamp(β€œ2000-01-01”), pd.Timestamp(β€œ2020-01-01”)). The calendar mapping is usually set with the map_years or map_to_data methods.

  • intervals – A list of Interval objects that should be appended to the calendar when it is initialized.

Example

Instantiate a custom calendar and appending target/precursor periods.

>>> import lilio
>>> calendar = lilio.Calendar(anchor="12-31")
>>> calendar  
Calendar(
    anchor='12-31',
    allow_overlap=False,
    mapping=None,
    intervals=None
)
property n_targets: int

Return the number of targets.

property n_precursors: int

Return the number of precursors.

property anchor
Return the anchor.
property allow_overlap
if overlapping intervals are allowed or not.
Type:

Returns the allow_overlap

property mapping: None | Literal['years', 'data', 'data-greedy']

Return the mapping of the calendar. Either None, β€œyears”, or β€œdata”.

add_intervals(role: Literal['target', 'precursor'], length: str, gap: str = '0d', n: int = 1) None[source]

Add one or more intervals to the calendar.

The interval can be a target or a precursor, and can be defined by its length, a possible gap between this interval and the preceding interval.

Parameters:
  • role – Either a β€˜target’ or β€˜precursor’ interval(s).

  • length – The length of the interval(s), in a format of β€˜5d’ for five days, β€˜2W’ for two weeks, or β€˜1M’ for one month.

  • gap – The gap between this interval and the preceding target/precursor interval. Same format as the length argument.

  • n – The number of intervals which should be added to the calendar. Defaults to 1.

map_years(start: int, end: int)[source]

Add a start and end year mapping to the calendar.

If the start and end years are the same, the intervals for only that single year are returned by calendar.get_intervals().

Parameters:
  • start – The first year for which the calendar will be realized

  • end – The last year for which the calendar will be realized

Returns:

The calendar mapped to the input start and end year.

map_to_data(input_data: pandas.Series | pandas.DataFrame | xarray.Dataset | xarray.DataArray, safe: bool = True)[source]

Map the calendar to input data period.

Stores the first and last intervals of the input data to the calendar, so that the intervals can cover the data to the greatest extent.

Parameters:
  • input_data – Input data for datetime mapping. Its index must be either pandas.DatetimeIndex, or an xarray time coordinate with datetime data.

  • safe – bool describing if data should be mapped in safe (makes sure intervals are data-filled) or greedy mode (interval created if there is any data), safe is default.

Returns:

The calendar mapped to the input data period.

get_intervals() pandas.DataFrame[source]

Retrieve updated intervals from the Calendar object.

show() pandas.DataFrame[source]

Display the intervals the Calendar will generate for the current setup.

Returns:

Dataframe containing the calendar intervals.

Return type:

pd.Dataframe

visualize(n_years: int = 3, interactive: bool = False, relative_dates: bool = False, show_length: bool = False, add_legend: bool = True, ax=None, **bokeh_kwargs) None[source]

Plot a visualization of the current calendar setup, to aid in user setup.

Note: The interactive visualization requires the bokeh package to be installed in the active Python environment.

Parameters:
  • n_years – Sets the maximum number of anchor years that should be shown. By default only the most recent 3 are visualized, to ensure that they fit within the plot.

  • interactive – If False, matplotlib will be used for the visualization. If True, bokeh will be used.

  • relative_dates – Toggles if the intervals should be displayed relative to the anchor date, or as absolute dates.

  • show_length – Toggles if the frequency of the intervals should be displayed. Defaults to False (Matplotlib plotter only).

  • add_legend – Toggles if a legend should be added to the plot (Matplotlib only)

  • ax – Matplotlib axis object to plot the visualization into.

  • **bokeh_kwargs – Keyword arguments to pass to Bokeh’s plotting.figure. See https://docs.bokeh.org/en/latest/docs/reference/plotting/figure.html for a list of possible keyword arguments.

property flat: pandas.DataFrame

Returns the flattened intervals.

lilio.calendar_shorthands.daily_calendar(anchor: str, length: str = '1d', n_targets: int = 1, n_precursors: int = 0, allow_overlap: bool = False) lilio.calendar.Calendar[source]

Instantiate a basic daily calendar with minimal configuration.

Set up a quick calendar revolving around intervals with day-based lengths. The intervals will extend back in time with as many intervals as fit within the cycle time of one year.

Parameters:
  • anchor – String in the form β€œ12-31” for December 31st. The first target interval will contain the anchor, while the precursor intervals are built back in time starting at this date.

  • length – The length of every target and precursor period.

  • n_targets – integer specifying the number of target intervals in a period.

  • n_precursors – Sets the maximum number of precursors of the Calendar. If 0, the amount will be determined by how many fit in each anchor year. If a value is provided, the intervals can either only cover part of the year, or extend over multiple years. In case of a large max_lag number where the intervals extend over multiple years, anchor years will be skipped to avoid overlapping intervals. To allow overlapping intervals, use the allow_overlap kwarg.

  • allow_overlap – Allows intervals to overlap between anchor years, if the max_lag is set to a high enough number that intervals extend over multiple years. False by default, to avoid train/test information leakage.

Returns:

An instantiated Calendar built according to the input kwarg specifications

Example

Instantiate a calendar counting towards Christmas in 3-days steps.

>>> import lilio
>>> calendar = lilio.daily_calendar(anchor='12-25', length="3d", n_precursors=3)
>>> calendar  
Calendar(
    anchor='12-25',
    allow_overlap=False,
    mapping=None,
    intervals=[
        Interval(role='target', length='3d', gap='0d'),
        Interval(role='precursor', length='3d', gap='0d'),
        Interval(role='precursor', length='3d', gap='0d'),
        Interval(role='precursor', length='3d', gap='0d')
    ]
)
lilio.calendar_shorthands.weekly_calendar(anchor: str, length: str = '1W', n_targets: int = 1, n_precursors: int = 0, allow_overlap: bool = False) lilio.calendar.Calendar[source]

Instantiate a basic monthly calendar with minimal configuration.

Set up a quick calendar revolving around intervals with week-based lengths. The precursor intervals will extend back in time with as many intervals as fit within the cycle time of one year (i.e. 52 - n_targets).

Note that the difference between this calendar and the daily_calendar revolves around the use of calendar weeks (Monday - Sunday), instead of 7-day periods.

Parameters:
  • anchor – Str in the form of β€œ40W”, denoting the week number. The first target interval will contain the anchor, while the precursor intervals are built back in time starting from this week.

  • length – The length of every precursor and target interval, e.g. β€˜2W’.

  • n_targets – integer specifying the number of target intervals in a period.

  • n_precursors – Sets the maximum number of precursors of the Calendar. If 0, the amount will be determined by how many fit in each anchor year. If a value is provided, the intervals can either only cover part of the year, or extend over multiple years. In case of a large max_lag number where the intervals extend over multiple years, anchor years will be skipped to avoid overlapping intervals. To allow overlapping intervals, use the allow_overlap kwarg.

  • allow_overlap – Allows intervals to overlap between anchor years, if the max_lag is set to a high enough number that intervals extend over multiple years. False by default, to avoid train/test information leakage.

Returns:

An instantiated Calendar built according to the input kwarg specifications

Example

Instantiate a calendar counting down the quarters (3 month periods) from december.

>>> import lilio
>>> calendar = lilio.weekly_calendar(anchor="W40", length="1W", n_precursors=2)
>>> calendar  
Calendar(
    anchor='W40-1',
    allow_overlap=False,
    mapping=None,
    intervals=[
        Interval(role='target', length='1W', gap='0d'),
        Interval(role='precursor', length='1W', gap='0d'),
        Interval(role='precursor', length='1W', gap='0d')
    ]
)
lilio.calendar_shorthands.monthly_calendar(anchor: str, length: str = '1M', n_targets: int = 1, n_precursors: int = 0, allow_overlap: bool = False) lilio.calendar.Calendar[source]

Instantiate a basic monthly calendar with minimal configuration.

Set up a quick calendar revolving around intervals with month-based lengths. The intervals will extend back in time with as many intervals as fit within the cycle time of one year.

Parameters:
  • anchor – Str in the form β€˜January’ or β€˜Jan’. he first target interval will contain the anchor, while the precursor intervals are built back in time starting at this Month.

  • length – The length of every target and precursor period, in the form β€˜1M’, β€˜2M’, etc.

  • n_targets – integer specifying the number of target intervals in a period.

  • n_precursors – Sets the maximum number of precursors of the Calendar. If 0, the amount will be determined by how many fit in each anchor year. If a value is provided, the intervals can either only cover part of the year, or extend over multiple years. In case of a large max_lag number where the intervals extend over multiple years, anchor years will be skipped to avoid overlapping intervals. To allow overlapping intervals, use the allow_overlap kwarg.

  • allow_overlap – Allows intervals to overlap between anchor years, if the max_lag is set to a high enough number that intervals extend over multiple years. False by default, to avoid train/test information leakage.

Returns:

An instantiated Calendar built according to the input kwarg specifications

Example

Instantiate a calendar counting down the quarters (3 month periods) from december.

>>> import lilio
>>> calendar = lilio.monthly_calendar(anchor='Dec', length="3M")
>>> calendar  
Calendar(
    anchor='12',
    allow_overlap=False,
    mapping=None,
    intervals=[
        Interval(role='target', length='3M', gap='0d'),
        Interval(role='precursor', length='3M', gap='0d'),
        Interval(role='precursor', length='3M', gap='0d'),
        Interval(role='precursor', length='3M', gap='0d')
    ]
)