Pandas Данные о ценах на акции в рабочие дни недели - PullRequest
7 голосов
/ 28 мая 2020

Мой вопрос отличается от следующего:

Вопрос1: Неделя месяца pandas Quesiton2: Номер недели месяца

В приведенном выше вопросе предполагается, что в неделе 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, но если вы go на страницу «https://aroussi.com/post/python-yahoo-finance» и используете авторов yfinance package, вы сможете получить некоторые данные о ценах для работы.

Функции, указанные выше, найдут 3-ю неделю месяца (все верно). Кроме того, он также установит пятницу этой недели.

Дайте мне знать, если вы заметите какие-либо проблемы с вопросом или его дубликат. Некоторое время я искал решение.

Ответы [ 4 ]

3 голосов
/ 02 июня 2020

Одним из способов может быть использование 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 верны, но поскольку вы сказали, что ваши данные - рабочие дни, это не имеет значения.

Версия pandas для использования в серии 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
2 голосов
/ 28 мая 2020

Мы можем легко изменить вашу функцию для работы с индексом:

# 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
0 голосов
/ 01 июня 2020

Хотя заголовок вопроса - «Pandas Неделя месяца», основываясь на ваших комментариях к другим ответам, кажется, что вы в первую очередь заинтересованы в определении «недели операционных расходов», которая является торговой неделей (т.е. с понедельника по Friday), который содержит третью пятницу.

Если вышеприведенное предположение и определение верны, то эта функция выполнит свою работу:

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])
0 голосов
/ 31 мая 2020
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...