Python中给出月份的第一个月

Gya*_*eda 12 python date

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

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

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

>> first_month_quarter(5)
4
Run Code Online (Sandbox Code Playgroud)

jon*_*rpe 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]
Run Code Online (Sandbox Code Playgroud)

一个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])
Run Code Online (Sandbox Code Playgroud)

结果:

quarter:    3.01457574242
firstMonthInQuarter1:   4.51578357209
firstMonthInQuarter2:   4.01768559763
first_month_quarter:    8.08281871176
Run Code Online (Sandbox Code Playgroud)

  • 当答案可能在以后出现时,提出速度声明总是有风险的.对于一千万次迭代,你的方法需要7.2秒,但我的答案中的两个是7.0和7.3.事实上,即使是"数学",其中一个也是7.6,所以它并不是那么糟糕.不是说你的解决方案不好(实际上这个地段之间没什么区别),只是说你可能想要回拨一下索赔:-)无论如何,感谢教育我'timeit`,我会之前没见过 (9认同)

pax*_*blo 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
Run Code Online (Sandbox Code Playgroud)

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

def firstMonthInQuarter(month):
    return (month - 1) // 3 * 3 + 1
Run Code Online (Sandbox Code Playgroud)

和:

def firstMonthInQuarter(month):
    return month - (month - 1) % 3
Run Code Online (Sandbox Code Playgroud)

第一个涉及将月份的整数除法转换为从零开始的月份以获得从零开始的季度,乘以将其转换回基于零的月份(但是在季度开始时的月份),然后再添加一个月份制作范围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
Run Code Online (Sandbox Code Playgroud)

第二个只是从月份本身减去四分之一(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
Run Code Online (Sandbox Code Playgroud)

  • @RhythemAggarwal,首先,我只提出了*两种*方法:-)在任何情况下,两者之间的时间差都足够小,根本不重要。除非您需要每秒执行数百万次操作,否则优化最好保留用于数据结构或算法选择等宏观事物。 (4认同)

Rob*_*obᵩ 13

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

for i in range(1,13):
    print i, first_month(i)
Run Code Online (Sandbox Code Playgroud)


Gya*_*eda 10

这是TigerhawkT3建议的答案.也许到目前为止最简洁的建议,显然也是最快的.

import math

def first_month_quarter(month):
    return int(math.ceil(month / 3.)) * 3 - 2
Run Code Online (Sandbox Code Playgroud)

例如:

>> first_month_quarter(5)
4
Run Code Online (Sandbox Code Playgroud)

  • 标准的`math`模块还有一个`ceil`函数,它在功能上与此类似. (2认同)
  • 我还建议将返回公式简化为`return 3*qrtr - 2`而不是`return qrtr +(qrtr-1)*2`.它的速度是测试速度的两倍多,可能是因为只需要获得一次"qrtr"的值.另外,你不必保存`qrtr`,将整个函数转换为`return int(math.ceil(month/3.))*3 - 2`.如果你切换到Python 3,你甚至不必调用`int`,因为Python 3的`ceil`已经返回一个`int`.如果您有很多记录可以使用,那就太好了. (2认同)

sam*_*gak 6

将查找表打包为 64 位文字:

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

# Python 3
def firstMonthOfQuarter(month):
    return (0x000aaa7774441110 >> (month << 2)) & 15
Run Code Online (Sandbox Code Playgroud)