Pandas - фильтрация данных за последний n месяц по запросу - PullRequest
0 голосов
/ 11 января 2020

Я хочу отфильтровать свой фрейм данных на основе столбца time с помощью функции query и получить строки с time за последний N месяц (или любые периоды времени).

В основном мне нужно что-то вроде:

df = df.query("time.isin(timeperiod('5M'))")

или

df = df.query("now() >= time >= now() - timeperiod('5M')")

Я пытаюсь создать шаблоны запросов для своих функций фильтра, и важно использовать query () function.

Обратите внимание, что функции timeperiod() и now() недоступны, и я использовал их для лучшего понимания нужного решения. Я имею в виду, пожалуйста, определите эти функции в своем решении.

Образец:

df = pd.DataFrame()
df['time1'] = pd.date_range('1/1/2019', periods=1000, freq='D')
df['time2'] = pd.date_range('1/1/2018', periods=1000, freq='D')

Образец данных может иметь некоторые другие столбцы.

Мне нужно отфильтровать данные, чтобы получить записи в течение последнего N месяца для каждого из указанных столбцов, используя query() функция. Например, я хочу записи с time1 за последние 2 месяца и time2 за последние 3 месяца. Например, получение записей о людях, которые были наняты в течение последних 3 месяцев и получили разрешение go в течение последних 2 месяцев.

ОБНОВЛЕНИЕ 1:

благодаря @ Jezrael Я мог бы получить now() функцию в query() следующим образом:

df = df.query("@pd.Timestamp('now') >= time")

конечно Timestamp можно заменить на 'to_datetime` или что-то еще.

Но проблема в том, что я пытаюсь получить временную метку для начала периода следующим образом:

df = df.query("time >= (@pd.Timestamp('now') + @pd.to_timedelta('30day'))")

Я получаю: Cannot convert input ... of type <class 'pandas._libs.tslibs.timedeltas.Timedelta'> to Timestamp

Снова с использованием DateOffset или других функций дельта времени, результат с похожая ошибка.

Но использование переменных для установки целевой даты (как упоминалось @ jezrael ) работает.

Я буду использовать переменные так как сейчас я не вижу другого пути, но я оставлю этот вопрос открытым, чтобы посмотреть, есть ли лучший способ.

1 Ответ

2 голосов
/ 11 января 2020

Используйте DateOffset для последних N месяцев, оба условия объединены в цепочку | для побитового OR:

now = pd.to_datetime('now')
last2 = now - pd.DateOffset(months=2)
last3 = now - pd.DateOffset(months=3)

df = df.query("(@now >= time1 >= @last2) | (@now >= time2 >= @last3)")
print(df)
         time1      time2
315 2019-11-12 2018-11-12
316 2019-11-13 2018-11-13
317 2019-11-14 2018-11-14
318 2019-11-15 2018-11-15
319 2019-11-16 2018-11-16
..         ...        ...
736 2021-01-06 2020-01-07
737 2021-01-07 2020-01-08
738 2021-01-08 2020-01-09
739 2021-01-09 2020-01-10
740 2021-01-10 2020-01-11

[153 rows x 2 columns]

Другое решение без query с boolean indexing:

df = df[(df.time1 <= pd.to_datetime('now')) & 
        (df.time1 >= pd.to_datetime('now')- pd.DateOffset(months=2))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...