以数字形式给出一个月(例如,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)
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)
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)
将查找表打包为 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)