повторная выборка панд в определенный день недели в месяце - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть фрейм данных Pandas, где я хотел бы делать выборку каждую третью пятницу месяца.

np.random.seed(0)
#requested output:
dates = pd.date_range("2018-01-01", "2018-08-31")
dates_df = pd.DataFrame(data=np.random.random(len(dates)), index=dates)
mask = (dates.weekday == 4) & (14 < dates.day) & (dates.day < 22)
dates_df.loc[mask]

enter image description here

Но когдапропущена третья пятница (например, опущена третья пятница февраля), я хочу получить последнее значение (по состоянию на 2018-02-15).Использование маски дает мне следующее значение (17 февраля вместо 15 февраля):

# remove February third Friday:
dates_df = dates_df.drop([pd.to_datetime("2018-02-16")])
mask = (dates.weekday == 4) & (14 < dates.day) & (dates.day < 22)
dates_df.loc[mask]

enter image description here

Использование ежемесячной повторной выборки в сочетании с loffset даетзначения на конец месяца со смещением индекса, что тоже не то, что я хочу:

from pandas.tseries.offsets import WeekOfMonth
dates_df.resample("M", loffset=WeekOfMonth(week=2, weekday=4)).last()

enter image description here

Есть ли альтернатива (желательно с помощью повторной выборки)без необходимости сначала повторять выборку до суточных значений, а затем добавлять маску (это занимает много времени для заполнения моего кадра данных)

1 Ответ

0 голосов
/ 04 октября 2018

Ваша вторая попытка направлена ​​в правильном направлении IIUC, вам просто нужно сделать повторную выборку, используя WeekOfMonth как правило, а не использовать его в качестве смещения:

dates_df.resample(WeekOfMonth(week=2, weekday=4)).asfreq().dropna()

Этот подход не сместит индекс, онследует просто возвращать данные за третью пятницу каждого месяца.

Работа с отсутствующей 3-ей пятницей:

С указанным выше кодом, если у вас пропущена третья пятница,весь месяц будет исключен.Но в зависимости от того, как вы хотите справиться с отсутствующими данными, вы можете bfill, ffill, pad .. вы можете изменить вышеизложенное на следующее:

dates_df.resample(rule=WeekOfMonth(week=2,weekday=4)).bfill().asfreq(freq='D').dropna()

Выше будет bfill пропущенная 3-я пятница со следующим значением.

Обновление : позволяет работать с фиксированным набором данных вместо np.random:

# create a smaller daterange
dates = pd.date_range("2018-05-01", "2018-08-31")

# create a data with only 1,2,3 values
data = [1,2,3] * int(len(dates)/3)

dates_df = pd.DataFrame(data=data, index=dates)
dates_df.head()

# Output:

2018-05-01  1
2018-05-02  2
2018-05-03  3
2018-05-04  1
2018-05-05  2

Теперь давайте проверим, как выглядят данные для 3-й пятницы каждого месяца, выбрав их вручную:

dates_df.loc[[
    pd.Timestamp('2018-05-18'),
    pd.Timestamp('2018-06-15'),
    pd.Timestamp('2018-07-20'),
    pd.Timestamp('2018-08-17')
]]

Output:

2018-05-18  3
2018-06-15  1
2018-07-20  3
2018-08-17  1

Если у вас нет пропущенных 3-х пятниц и запустите код, предоставленный ранее:

dates_df.resample(rule=WeekOfMonth(week=2,weekday=4)).asfreq().dropna()

Будет выдавать следующий вывод:

2018-05-18  3
2018-06-15  1
2018-07-20  3
2018-08-17  1

Как вы можете видеть, индекс здесь не был смещен и возвращал точные значения для 3-й пятницы каждого месяца.

Теперь предположим, что у вас пропущены 3-ий пятницы, в зависимости от того, как вы хотите это сделать (используйте предыдущее значение: ffill или следующее значение bfill):

  • pad / ffill: распространить последнее действительное наблюдение вперед до следующего действительного
  • backfill / bfill: использовать NEXT vaнаблюдение за крышкой, чтобы восполнить пробел'M' (конец месяца), а затем вы смещаете (смещаете вперед) индекс на 3-ю пятницу каждого месяца.

    Как вы можете видеть до смещения, это выглядит так:

    dates_df.resample(rule='M').asfreq().dropna()
    
    # Output
    
    2018-05-31  1
    2018-06-30  1
    2018-07-31  2
    2018-08-31  3
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...