我的问题与以下内容不同:
问题1:Week of a month pandas Quesiton2:Week number of the month
上述问题假设一周中有7天。它尝试计算每周7天的数量。我的数据由(工作日)每日价格组成,由于市场因节假日休市,因此有时可能会缺少一周中的某些天。
我的问题是如何找到一个给定日期的月份。请注意,我突出显示了“给定日期”,因为此过程每天都会处理,因此任何看起来 提前 直到月底的答案都将无法正常工作。
我的尝试一直是不理想的展望:
def is_third_friday(s):
d = datetime.datetime.strptime(s, '%Y-%m-%d')
return d.weekday() == 5 and 15 <= d.day <= 21
dow = deepcopy(data['Close'] * np.nan).to_frame()
dow.columns = ['OpexFriday']
dow['next_date'] = pd.Series([str(i.date() + datetime.timedelta(days=1)) for i in dow.index]).values
dow['OpexFriday'] = pd.Series([is_third_friday(str(i)) for i in dow['next_date']]).values
dow['OpexWeek'] = (dow['OpexFriday'] * 1).replace(0, np.nan).fillna(method='bfill', limit=4).replace(np.nan, 0) == True
我不知道如何提供一些示例data
,但是如果您转到“ https://aroussi.com/post/python-yahoo-finance”页面并使用作者yfinance软件包,您将能够获取一些价格数据以供使用。
以上功能将找到每月的第3周(全部为True)。此外,它也会设置该周的星期五。
请让我知道您是否对该问题有任何疑问,或者是否有重复的问题。我已经搜索了一段时间以寻找解决方案。
答案 0 :(得分:3)
一种方法是使用timedelta
将任何日期更改为下一个星期五,然后检查下一个星期五是否在15到21之间。
from datetime import datetime, timedelta
def OpexWeek (s):
d = datetime.strptime(s, '%Y-%m-%d')
day = (d+timedelta(days=(4-d.weekday())%7)).day
return (day>=15) & (day<=21)
然后您得到
#for the example the second Friday of June 2020:
OpexWeek('2020-06-12')
False
# the Monday after is True because part of the OpexWeek
OpexWeek('2020-06-15')
True
注意:要知道的一件事是OpexWeek之前的周六和周日为True,但是由于您说的是工作日,因此这无关紧要。
在datetime系列上使用的熊猫版本可能是:
def OpexWeekPd (ser):
return (ser+pd.to_timedelta((4-ser.dt.weekday)%7, unit='d')).dt.day.between(15,21)
举一个小例子:
print (
pd.DataFrame({'date':pd.bdate_range('2020-06-01', '2020-06-30').astype(str)})
.assign(isOpexWeek=lambda x: x['date'].apply(OpexWeek),
isIpexWeekPd=lambda x: OpexWeekPd(pd.to_datetime(x['date'])))
)
date isOpexWeek isIpexWeekPd
0 2020-06-01 False False
1 2020-06-02 False False
2 2020-06-03 False False
3 2020-06-04 False False
4 2020-06-05 False False
5 2020-06-08 False False
6 2020-06-09 False False
7 2020-06-10 False False
8 2020-06-11 False False
9 2020-06-12 False False
10 2020-06-15 True True
11 2020-06-16 True True
12 2020-06-17 True True
13 2020-06-18 True True
14 2020-06-19 True True
15 2020-06-22 False False
16 2020-06-23 False False
17 2020-06-24 False False
18 2020-06-25 False False
19 2020-06-26 False False
20 2020-06-29 False False
21 2020-06-30 False False
答案 1 :(得分:2)
我们可以轻松地修改您的函数以使用索引:
# sample data
dow = pd.DataFrame(index=pd.date_range('2020-01-01', '2020-01-31'),
columns=['OpexFriday'])
isFriday = dow.index.dayofweek == 5
thirdWeek = dow.index.day.to_series().between(15,21)
# third Friday
dow['OpexFriday'] = (isFriday & thirdWeek).values
# third work week
dow['OpexWeek'] = dow['OpexFriday'].where(dow['OpexFriday']).bfill(limit=4).fillna(0)
# extract the third week:
dow[dow['OpexWeek']==1]
输出:
OpexFriday OpexWeek
2020-01-14 False 1.0
2020-01-15 False 1.0
2020-01-16 False 1.0
2020-01-17 False 1.0
2020-01-18 True 1.0
答案 2 :(得分:0)
import datetime
from math import ceil
def week_of_month(dt):
""" Returns the week of the month for the specified date.
"""
adjusted_dom = dt.day + dt.replace(day=1).day
return int(ceil(adjusted_dom / 7.0))
def week_of_month_from_str(d_str):
return week_of_month(datetime.datetime.strptime(d_str, '%Y-%m-%d'))
assert week_of_month_from_str("2020-03-02") == 1
assert week_of_month_from_str("2020-03-07") == 2
assert week_of_month_from_str("2020-03-13") == 2
assert week_of_month_from_str("2020-03-14") == 3
assert week_of_month_from_str("2020-03-20") == 3
assert week_of_month_from_str("2020-06-01") == 1
assert week_of_month_from_str("2020-06-06") == 1
assert week_of_month_from_str("2020-06-07") == 2
assert week_of_month_from_str("2020-06-08") == 2
答案 3 :(得分:0)
尽管问题的标题是“本月的熊猫周”,但根据您对其他答案的评论,您似乎最有兴趣确定“ OpEx周”,即交易周(即星期一至星期五)包含第三个星期五。
如果以上假设和定义正确,那么此函数将完成工作:
def isOpexWeek(d):
first_week_day = datetime.date(d.year, d.month, 1).weekday()
first_friday = 1 + ((4 - first_week_day + 7) % 7)
third_friday = first_friday + 14
return d.day in range(third_friday-4, third_friday+1)
dow = pd.DataFrame(index=pd.date_range('2020-01-01', '2020-02-01'), columns=['OpexWeek'])
dow['OpexWeek'] = dow.index.to_series().apply(isOpexWeek)
print(dow)
dow = pd.DataFrame(index=pd.date_range('2020-01-01', '2021-01-01'), columns=['OpexWeek'])
dow['OpexWeek'] = dow.index.to_series().apply(isOpexWeek)
print(dow[dow.OpexWeek])