Проблема
Предположим, у меня есть временной ряд данных df
(pandas
dataframe), и в некоторые дни я хочу выделить его, содержащийся в другом кадре данных с именем sample_days
:
>>> df
foo bar
2020-01-01 00:00:00 0.360049 0.897839
2020-01-01 01:00:00 0.285667 0.409544
2020-01-01 02:00:00 0.323871 0.240926
2020-01-01 03:00:00 0.921623 0.766624
2020-01-01 04:00:00 0.087618 0.142409
... ... ...
2020-12-31 19:00:00 0.145111 0.993822
2020-12-31 20:00:00 0.331223 0.021287
2020-12-31 21:00:00 0.531099 0.859035
2020-12-31 22:00:00 0.759594 0.790265
2020-12-31 23:00:00 0.103651 0.074029
[8784 rows x 2 columns]
>>> sample_days
month day
0 3 16
1 7 26
2 8 15
3 9 26
4 11 25
Я хочу нарезать df
с днями, указанными в sample_days
. Я могу сделать это с помощью циклов (см. Ниже). Тем не менее, есть ли способ избежать циклов (как это более эффективно)? Результатом должен быть фрейм данных с именем sample
, подобный следующему:
>>> sample
foo bar
2020-03-16 00:00:00 0.707276 0.592614
2020-03-16 01:00:00 0.136679 0.357872
2020-03-16 02:00:00 0.612331 0.290126
2020-03-16 03:00:00 0.276389 0.576996
2020-03-16 04:00:00 0.612977 0.781527
... ... ...
2020-11-25 19:00:00 0.904266 0.825501
2020-11-25 20:00:00 0.269589 0.050304
2020-11-25 21:00:00 0.271814 0.418235
2020-11-25 22:00:00 0.595005 0.973198
2020-11-25 23:00:00 0.151149 0.024057
[120 rows x 2 columns
, который представляет собой просто df
, разрезанный на правильные дни.
Мое (медленное) решение
Мне удалось сделать это, используя циклы for и pd.concat
:
sample = pd.concat([df.loc[df.index.month.isin([sample_day.month]) &
df.index.day.isin([sample_day.day])]
for sample_day in sample_days.itertuples()])
, основанные на конкатенации нескольких дней в разрезе по методу, указанному здесь . Это дает желаемый результат, но довольно медленно. Например, использование этого метода для получения первого дня каждого месяца занимает в среднем 0,2 секунды, тогда как простой вызов df.loc[df.index.day == 1]
(предположительно, избегая python для циклов под колпаком) происходит примерно в 300 раз быстрее. Тем не менее, это срез только на день - я нарезаю на месяц и день.
Извините, если на этот вопрос ответили где-то еще - я долго искал, но, возможно, не использовал правильные ключевые слова.