8000 add API to change a time axis frequency · Issue #1119 · larray-project/larray · GitHub
[go: up one dir, main page]

Skip to content
add API to change a time axis frequency #1119
Open
@gdementen

Description

@gdementen

Yesterday I created the following function (for vs):

def monthly_to_quarterly(axis_or_group, first_year=None, last_year=None):
    """
    Produces a tuple of groups to aggregate an array with a monthly axis to a quarterly axis
    
    The monthly axis must have labels using the "{YYYY}M{M}" format
    (M goes from 1 to 12, not 01 to 12).
    The quarterly axis will have labels using the "{YYYY}Q{Q}" format.
    
    Parameters
    ----------
    axis_or_group : Axis or Group
        Original monthly axis (or selection on it).
    first_year : int, optional
        First year taken into account. Defaults to the first year present on the axis.
    last_year : int, optional
        Last year taken into account. Defaults to the last year present on the axis.        

    Returns
    -------
    tuple
        Groups which can be used to aggregate an array with the original monthly axis
        into a quarterly axis

    Examples
    --------
    >>> time = Axis(f"2024M3..2024M10", 'time')
    >>> arr = ndtest(time)
    >>> arr
    time  2024M3  2024M4  2024M5  2024M6  2024M7  2024M8  2024M9  2024M10
               0       1       2       3       4       5       6        7    
    >>> quarter_months = monthly_to_quarterly(time)
    >>> quarter_months
    (time['2024M3'] >> '2024Q1',
     time['2024M4', '2024M5', '2024M6'] >> '2024Q2',
     time['2024M7', '2024M8', '2024M9'] >> '2024Q3',
     time['2024M10'] >> '2024Q4')
    >>> arr.sum(quarter_months)
    time  2024Q1  2024Q2  2024Q3  2024Q4
               0       6      15       7
    """
    labels = axis_or_group.labels if isinstance(axis_or_group, Axis) else axis_or_group.eval()
    axis = axis_or_group if isinstance(axis_or_group, Axis) else axis_or_group.axis
    group = axis[:] if isinstance(axis_or_group, Axis) else axis_or_group
    if first_year is None or last_year is None:
        years = set(int(label[:4]) for label in labels)
        if first_year is None:
            first_year = min(years)
        if last_year is None:
            last_year = max(years)
    quarters = []
    for y in range(first_year, last_year + 1):
        for q in range(1, 5):
            quarter_months = f"{y}M{(q - 1) * 3 + 1}..{y}M{(q - 1) * 3 + 3}"
            # support axes/selections which do not start at the first month
            quarter_months_in_selection = group.intersection(quarter_months)

            # avoid "empty" quarters, if the axis has no month for some quarters
            if quarter_months_in_selection:
                # transform the LSet returned by .intersection() to a normal LGroup
                # this step is not strictly necessary but produces nicer groups            
                quarter_months_in_selection = axis[quarter_months_in_selection.eval()]
                quarters.append(quarter_months_in_selection >> f'{y}Q{q}')
    return tuple(quarters)

I think we should generalize this further and add something which can do this kind of conversion in LArray.

A few references:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0