Search code examples
pythonpandaszipwindowperiod

Calculating quarter length in pandas.period


Sample code:

months = [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sept, Oct, Nov, Dec]
months = pd.period_range(start='2020-01', periods=12, freq='M')

for start, end in zip(months, months[11:]):

end_q = end.qyear

print(start, end, end_q)

# Output:
2020-01 2020-12 2020

This code returns a window with 12 months (start, end) and the last quarter of the window (end_q).

My question is, how can I measure the percentage of the end_q over the full window (start, end)?

I know how to measure the days of the first month in the window with:

  first_month = start.month

  # number of days in first month (e.g., Jan)
  first_month_days = start.days_in_month

Now I am wondering how I could measure the last three months of the window, any suggestion is welcome! Thanks!

EDIT

Example outcome (note I am assuming that each month is composed by 30 days for simplicity):

  • If window size is 12 months (360 days) and the last quarter (Oct, Nov, Dec) is composed by 90 days, the outcome should be: 90 / 360 = 0.25
  • If windows size is 15 months (450) and last quarter (in the window size) now will be Jan, Feb, Mar (of the next year), the outcome should be: 90 / 450 = 0.2

Solution

  • To get the ranges for the quarters, you could do the following to look at multiples of threes which could dynamically look at multiple years:

    n = 3
    months = pd.period_range(start='2020-01', periods=12, freq='M')    
    for i in range(len(months)):
        if i%n == 0:
            print(months[i], months[i+2], months[i+2].qyear, n/len(months))
    
    2020-01 2020-03 2020 0.25
    2020-04 2020-06 2020 0.25
    2020-07 2020-09 2020 0.25
    2020-10 2020-12 2020 0.25
    

    This method basically

    To get just the fourth quarter (again this would work for a period of multiple years assuming a 12, 24, 36 months, etc. period that begins in January), you could do an if statement for October where the remainder of (x+3)/12 equals 0, so that would return 9, 21, 33, etc. which would be the indexes for October across multiple years:

    n=3
    months = pd.period_range(start='2020-01', periods=48, freq='M')
    for i in range(len(months)):
        if i>0 and (i+n)%12 == 0:
            print(months[i], months[i+2], months[i+2].qyear, n/len(months))
    
    2020-10 2020-12 2020 0.0625
    2021-10 2021-12 2021 0.0625
    2022-10 2022-12 2022 0.0625
    2023-10 2023-12 2023 0.0625
    

    Note I canged to periods=48 in the above code. If you change to periods=12, then that would return:

    2020-10 2020-12 2020 0.25