Python中给出月份的第一个月

时间:2015-03-31 18:25:51

标签: python date

以数字形式给出一个月(例如,2月为2),您如何找到其各自季度的第一个月(例如,1月份为1)?

我阅读了datetime模块文档和他们的日期时间函数的Pandas文档,它们应该是相关的,但我找不到解决这个问题的函数。

基本上,我想要了解的是如何生成类似下面的函数,给定月份 x ,输出对应于 x的第一个月的数字的季度。

>> first_month_quarter(5)
4

5 个答案:

答案 0 :(得分:20)

它不是那么漂亮,但如果速度很重要,那么简单的列表查找会扼杀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]

timeit比较表明这大约是TigerhawkT3数学方法的两倍。


测试脚本:

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])

结果:

quarter:    3.01457574242
firstMonthInQuarter1:   4.51578357209
firstMonthInQuarter2:   4.01768559763
first_month_quarter:    8.08281871176

答案 1 :(得分:19)

这是一个需要转换的简单映射函数:

1 2 3 4 5 6 7 8 9 10 11 12
           |
           V
1 1 1 4 4 4 7 7 7 10 10 10

这可以通过多种方式进行积分计算,其中两种是:

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

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

第一个涉及将月份的整数除法转换为从零开始的月份以获得从零开始的季度,乘以将其转换回基于零的月份(但是开始的月份季度的>,然后再添加一个以产生范围1..12

month  -1  //3  *3  +1
-----  --  ---  --  --
    1   0    0   0   1
    2   1    0   0   1
    3   2    0   0   1
    4   3    1   3   4
    5   4    1   3   4
    6   5    1   3   4
    7   6    2   6   7
    8   7    2   6   7
    9   8    2   6   7
   10   9    3   9  10
   11  10    3   9  10
   12  11    3   9  10

第二个只是从月份中减去四分之一(0,1,2)内的位置以获得起始月份。

month(a)  -1  %3(b)  a-b
--------  --  -----  ---
       1   0      0    1
       2   1      1    1
       3   2      2    1
       4   3      0    4
       5   4      1    4
       6   5      2    4
       7   6      0    7
       8   7      1    7
       9   8      2    7
      10   9      0   10
      11  10      1   10
      12  11      2   10

答案 2 :(得分:13)

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

for i in range(1,13):
    print i, first_month(i)

答案 3 :(得分:10)

以下是TigerhawkT3建议的答案。也许到目前为止最精简的建议,显然也是最快的。

import math

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

例如:

>> first_month_quarter(5)
4

答案 4 :(得分:2)

将查找表打包成64位字面值:

def firstMonthOfQuarter(month):
    return (0x000aaa7774441110L >> (month << 2)) & 15