我下面的工作代码计算日期/月份范围,但我使用的是 Pandas 库,我想摆脱它。
import pandas as pd
dates=pd.date_range("2019-12","2020-02",freq='MS').strftime("%Y%m%d").tolist()
#print dates : ['20191101','20191201','20200101','20200201']
df=(pd.to_datetime(dates,format="%Y%m%d") + MonthEnd(1)).strftime("%Y%m%d").tolist()
#print df : ['20191130','20191231','20200131','20200229']
如何在不使用 Pandas 的情况下重写此代码?
我不想使用 Pandas 库,因为我通过 Oozie 触发我的工作,而且我们没有在所有节点上安装 Pandas。
答案 0 :(得分:0)
Pandas 在使用标准库 datetime 模块没有的日期时间时提供了一些很好的功能(如频率或 MonthEnd
)。你必须自己重现这些。
import datetime as DT
def next_first_of_the_month(dt):
"""return a new datetime where the month has been increased by 1 and
the day is always the first
"""
new_month = dt.month + 1
if new_month == 13:
new_year = dt.year + 1
new_month = 1
else:
new_year = dt.year
return DT.datetime(new_year, new_month, day=1)
start, stop = [DT.datetime.strptime(dd, "%Y-%m") for dd in ("2019-11", "2020-02")]
dates = [start]
cd = next_first_of_the_month(start)
while cd <= stop:
dates.append(cd)
cd = next_first_of_the_month(cd)
str_dates = [d.strftime("%Y%m%d") for d in dates]
print(str_dates)
# prints: ['20191101', '20191201', '20200101', '20200201']
end_dates = [next_first_of_the_month(d) - DT.timedelta(days=1) for d in dates]
str_end_dates = [d.strftime("%Y%m%d") for d in end_dates]
print(str_end_dates)
# prints ['20191130', '20191231', '20200131', '20200229']
我在这里使用了一个函数来获取对应于输入日期时间的下个月第一天的日期时间。遗憾的是,timedelta
不适用于月份,并且添加 30 天当然是不可行的(并非所有月份都有 30 天)。
然后是一个 while
循环以获取该月的前几天直到停止日期的序列。
为了获得月底,再次获得列表中每个日期时间的下一个第一天,然后减去一天。