#python #pandas #datetime
Вопрос:
Я хотел бы получать значения через каждый n-й час из фрейма данных Pandas. Фрейм данных использует столбец DateTime в качестве индекса, как это:
Value A Value B Value C
timestamp
2021-03-29 23:58:59.443000 00:00 0.7 0.2 0.0
2021-03-29 23:58:59.458000 00:00 0.0 0.1 0.1
2021-03-29 23:58:59.474000 00:00 0.3 0.0 0.2
2021-03-29 23:59:59.446000 00:00 0.2 0.0 0.0
2021-03-29 23:59:59.461000 00:00 0.0 0.0 0.5
Теперь я хотел бы извлекать значения через каждый n-й час. Каков наилучший способ сделать это? Единственный способ, который я могу придумать прямо сейчас, — это создать список с датами, в которые должны быть извлечены значения, затем пройтись по этому списку, найти дату в кадре данных с наименьшей разницей и получить значения на эту дату. Но мне кажется, что это довольно плохая практика.
Комментарии:
1. Возможно, что-то вроде:
df.index.dt.hour.isin([1, 3, 5, 7])
что-то в этом роде?2. Выглядит очень многообещающе, попробую сразу!
3. Однако работает ли это с данными, охватывающими более одного дня?
4. Другое предложение, попробуйте
df.asfreq
, можетdf.asfreq("nH")
быть, или повторите выборкуdf.resample("nH").first()
, замените n числом или даже между временами в зависимости от того, что вы хотите
Ответ №1:
Используйте asof
слияние. Это приведет к объединению всей строки за ближайшее время в вашем кадре данных с почасовой частотой. Вы можете изменить направление, чтобы быть ближе всего в будущем или прошлом, а не в любом из направлений.
import pandas as pd
# Series of hours that span the range of the Index
s = pd.Series(pd.date_range(df.index.min().floor('H'), df.index.max().ceil('H'), freq='H'),
name='times')
pd.merge_asof(s, df.reset_index(), left_on='times', right_on='timestamp', direction='nearest')
times timestamp ValueA ValueB ValueC
0 2021-03-29 23:00:00 00:00 2021-03-29 23:58:59.443000 00:00 0.7 0.2 0.0
1 2021-03-30 00:00:00 00:00 2021-03-29 23:59:59.461000 00:00 0.0 0.0 0.5
Комментарии:
1. Будет ли это работать для данных, охватывающих более одного дня?
2. Зависит от того, чего ты хочешь. Если вы хотите получить ближайшее значение 2010-01-01 01:00:00, то да, это сработает. Но если вы хотите, чтобы время, ближайшее к часу 01:00:00, не зависело от даты, вы все равно можете его использовать, но вам нужно будет превратить свое время в метки времени и объединить таким образом, хотя необходимо учитывать цикличность 24 == 0.
3. Спасибо за разъяснение!