I have a data frame consisting of some columns, where the index is datetime, i.e. it looks something like:
df =
col1 col2 col3 col4 col5
date
2021-01-01 00:00:00+01:00 55.646134 1.00 -3890.12 2437.47 4.716594
2021-01-01 01:00:00+01:00 55.646134 2.00 -3786.65 2908.26 4.716594
2021-01-01 02:00:00+01:00 55.646134 3.00 -3694.92 3123.63 4.716594
2021-01-01 03:00:00+01:00 55.646134 4.00 -3619.17 3251.61 4.716594
2021-01-02 00:00:00+01:00 179.775434 -743.27 1352.90 1647.35 81.397542
2021-01-02 01:00:00+01:00 179.775434 -1184.25 752.35 2081.33 81.397542
2021-01-02 02:00:00+01:00 179.775434 -1448.93 -76.22 2306.36 81.397542
2021-01-02 03:00:00+01:00 179.775434 -1465.47 -1016.00 2091.12 81.397542
....
Now if I do something like:
df_grouped = list(df.groupby(df.index.hour))
Then I get a list of data frames where each group has either hour 00:00:00+01:00, 01:00:00+01:00, 02:00:00+01:00 etc. Hence 24 different groups in my case.
However, what I would like is to get them grouped by the hour, but ALSO including some integer of the previous and next hour, i.e. the resulting groups for the df above would instead of:
df_group1 =
col1 col2 col3 col4 col5
date
2021-01-01 00:00:00+01:00 55.646134 1.00 -3890.12 2437.47 4.716594
2021-01-02 00:00:00+01:00 179.775434 -743.27 1352.90 1647.35 81.397542
df_group2 =
col1 col2 col3 col4 col5
date
2021-01-01 01:00:00+01:00 55.646134 2.00 -3786.65 2908.26 4.716594
2021-01-02 01:00:00+01:00 179.775434 -1184.25 752.35 2081.33 81.397542
df_group3 =
col1 col2 col3 col4 col5
date
2021-01-01 02:00:00+01:00 55.646134 3.00 -3694.92 3123.63 4.716594
2021-01-02 02:00:00+01:00 179.775434 -1448.93 -76.22 2306.36 81.397542
df_group4 =
col1 col2 col3 col4 col5
date
2021-01-01 03:00:00+01:00 55.646134 4.00 -3619.17 3251.61 4.716594
2021-01-02 03:00:00+01:00 179.775434 -1465.47 -1016.00 2091.12 81.397542
Become:
df_group1_true =
col1 col2 col3 col4 col5
date
2021-01-01 00:00:00+01:00 55.646134 1.00 -3890.12 2437.47 4.716594
2021-01-01 01:00:00+01:00 55.646134 2.00 -3786.65 2908.26 4.716594
2021-01-02 00:00:00+01:00 179.775434 -743.27 1352.90 1647.35 81.397542
2021-01-02 01:00:00+01:00 179.775434 -1184.25 752.35 2081.33 81.397542
df_group2_true =
col1 col2 col3 col4 col5
date
2021-01-01 00:00:00+01:00 55.646134 1.00 -3890.12 2437.47 4.716594
2021-01-01 01:00:00+01:00 55.646134 2.00 -3786.65 2908.26 4.716594
2021-01-01 02:00:00+01:00 55.646134 3.00 -3694.92 3123.63 4.716594
2021-01-02 00:00:00+01:00 179.775434 -743.27 1352.90 1647.35 81.397542
2021-01-02 01:00:00+01:00 179.775434 -1184.25 752.35 2081.33 81.397542
2021-01-02 02:00:00+01:00 179.775434 -1448.93 -76.22 2306.36 81.397542
df_group3_true =
col1 col2 col3 col4 col5
date
2021-01-01 01:00:00+01:00 55.646134 2.00 -3786.65 2908.26 4.716594
2021-01-01 02:00:00+01:00 55.646134 3.00 -3694.92 3123.63 4.716594
2021-01-01 03:00:00+01:00 55.646134 4.00 -3619.17 3251.61 4.716594
2021-01-02 01:00:00+01:00 179.775434 -1184.25 752.35 2081.33 81.397542
2021-01-02 02:00:00+01:00 179.775434 -1448.93 -76.22 2306.36 81.397542
2021-01-02 03:00:00+01:00 179.775434 -1465.47 -1016.00 2091.12 81.397542
df_group4_true =
col1 col2 col3 col4 col5
date
2021-01-01 02:00:00+01:00 55.646134 3.00 -3694.92 3123.63 4.716594
2021-01-01 03:00:00+01:00 55.646134 4.00 -3619.17 3251.61 4.716594
2021-01-02 02:00:00+01:00 179.775434 -1448.93 -76.22 2306.36 81.397542
2021-01-02 03:00:00+01:00 179.775434 -1465.47 -1016.00 2091.12 81.397542
In this example data set here there are no 23:00:00+01:00, but obviously if you were on 00:00:00+01:00, the previous datetime to include should be 23:00:00+01:00 and so forth.
The way I do it now is actually by doing df_grouped = list(df.groupby(df.index.hour)) which will get me 24 data frames (one for each hour), and then something like:
additional_hours = 1 # How many +/- hours I want to expand each group with.
df_list_final = [
pd.concat(
[df[(i + j) % 24][1] for j in range(-additional_hours, additional_hours + 1)]
).sort_index()
for i in range(len(df))
]
And this works. However, I was wondering if there were a more elegant way of doing it with just some kind of groupby instead of having to concatenating a bunch of data frames all the time.