Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First month of quarter given month in Python

Tags:

python

date

Given a month in numeric form (e.g., 2 for February), how do you find the first month of its respective quarter (e.g., 1 for January)?

I read through the datetime module documentation and the Pandas documentation of their datetime functions, which ought to be relevant, but I could not find a function that solves this problem.

Essentially, what I am trying to understand is how I could produce a function like the one below that, given month x, outputs the number corresponding to the first month of x's quarter.

>> first_month_quarter(5)
4
like image 961
Gyan Veda Avatar asked Mar 31 '15 18:03

Gyan Veda


People also ask

How do you convert a quarter to a month?

Notice how it uses the formula quarter = (moy + 2) / 3 . Therefore, to find the starting month of a quarter, we just need to rearrange it in terms of moy - moy = quarter * 3 - 2 .


1 Answers

It's not so pretty, but if speed is important a simple list lookup slaughters math:

def quarter(month, quarters=[None, 1, 1, 1, 4, 4, 4,
                             7, 7, 7, 10, 10, 10]):
    """Return the first month of the quarter for a given month."""
    return quarters[month]

A timeit comparison suggests this is about twice as fast as TigerhawkT3's mathematical approach.


Test script:

import math

def quarter(month, quarters=[None, 1, 1, 1, 4, 4, 4,
                             7, 7, 7, 10, 10, 10]):
    """Return the first month of the quarter for a given month."""
    return quarters[month]

def firstMonthInQuarter1(month):
    return (month - 1) // 3 * 3 + 1

def firstMonthInQuarter2(month):
    return month - (month - 1) % 3

def first_month_quarter(month):
    return int(math.ceil(month / 3.)) * 3 - 2

if __name__ == '__main__':
    from timeit import timeit
    methods = ['quarter', 'firstMonthInQuarter1', 'firstMonthInQuarter2',
               'first_month_quarter']
    setup = 'from __main__ import {}'.format(','.join(methods))
    results = {method: timeit('[{}(x) for x in range(1, 13)]'.format(method),
                              setup=setup)
               for method in methods}
    for method in methods:
        print '{}:\t{}'.format(method, results[method])

Results:

quarter:    3.01457574242
firstMonthInQuarter1:   4.51578357209
firstMonthInQuarter2:   4.01768559763
first_month_quarter:    8.08281871176
like image 94
jonrsharpe Avatar answered Oct 03 '22 19:10

jonrsharpe