如何聚合 Pandas DataFrame 行,在 Python 中的日期时间索引值之间具有一致的时间增量?
How to aggregate Pandas DataFrame rows with consistent timedelta between Datetime index values in Python?
我有一个 Pandas DataFrame,它以 2 分钟的间隔进行连续测量,我已将其过滤为仅包含某些值。此过程在 DataFrame 中创建子组,其测量间隔为 2 分钟。我想聚合每个子组,以便获得每个子组的平均值,并根据相应组的最后一个日期时间索引对平均值进行索引。例如:
原始数据帧
2020-06-09 08:44:00 1
2020-06-09 08:46:00 2
2020-06-09 08:48:00 3
2020-06-09 08:50:00 4
2020-06-09 09:06:00 10
2020-06-09 09:08:00 12
2020-06-09 09:10:00 14
2020-06-09 10:14:00 20
2020-06-09 10:16:00 10
2020-06-09 10:18:00 5
2020-06-09 10:20:00 2
新数据帧
2020-06-09 08:50:00 2.5
2020-06-09 09:10:00 12
2020-06-09 10:20:00 9.25
在原始DataFrame中,有三个子组,其中索引之间的间隔保持恒定为2分钟。新的 DataFrame 将只有最后一个索引具有平均值(或任何聚合)值。
过去,我创建了一个单独的列,其中包含日期时间索引之间的时间差,并通过一些不必要的复杂循环,查找大于首选值的时间差,然后汇总之前的测量值并将它们添加到一个单独的列中随着我循环而增长的数据框。我知道这个过程非常低效,所以我一直在寻找一种更快、更优雅的方式。
我们可以将日期时间索引变成一个列,根据那些取last
时间值和mean
列值的值取diff
between rows to find the relative time difference between values. Create a boolean mask where values are gt
the expected time period and groupby agg
。然后恢复索引:
# Make the index a Series which is has more computation options
new_df = df.reset_index()
new_df = (
new_df.groupby(
# Find where index does not follow pattern of 2 minute intervals
new_df['index'].diff().gt(pd.Timedelta(minutes=2)).cumsum()
).agg({
# Get the last index value and the average of the column values
'index': 'last', 'col': 'mean'
}).set_index('index').rename_axis(index=None) # restore index
)
new_df
:
col
2020-06-09 08:50:00 2.50
2020-06-09 09:10:00 12.00
2020-06-09 10:20:00 9.25
设置:
import pandas as pd
df = pd.DataFrame({
'col': [1, 2, 3, 4, 10, 12, 14, 20, 10, 5, 2]
}, index=pd.to_datetime(
['2020-06-09 08:44:00', '2020-06-09 08:46:00',
'2020-06-09 08:48:00', '2020-06-09 08:50:00',
'2020-06-09 09:06:00', '2020-06-09 09:08:00',
'2020-06-09 09:10:00', '2020-06-09 10:14:00',
'2020-06-09 10:16:00', '2020-06-09 10:18:00',
'2020-06-09 10:20:00']
))
df
:
col
2020-06-09 08:44:00 1
2020-06-09 08:46:00 2
2020-06-09 08:48:00 3
2020-06-09 08:50:00 4
2020-06-09 09:06:00 10
2020-06-09 09:08:00 12
2020-06-09 09:10:00 14
2020-06-09 10:14:00 20
2020-06-09 10:16:00 10
2020-06-09 10:18:00 5
2020-06-09 10:20:00 2
我有一个 Pandas DataFrame,它以 2 分钟的间隔进行连续测量,我已将其过滤为仅包含某些值。此过程在 DataFrame 中创建子组,其测量间隔为 2 分钟。我想聚合每个子组,以便获得每个子组的平均值,并根据相应组的最后一个日期时间索引对平均值进行索引。例如:
原始数据帧
2020-06-09 08:44:00 1
2020-06-09 08:46:00 2
2020-06-09 08:48:00 3
2020-06-09 08:50:00 4
2020-06-09 09:06:00 10
2020-06-09 09:08:00 12
2020-06-09 09:10:00 14
2020-06-09 10:14:00 20
2020-06-09 10:16:00 10
2020-06-09 10:18:00 5
2020-06-09 10:20:00 2
新数据帧
2020-06-09 08:50:00 2.5
2020-06-09 09:10:00 12
2020-06-09 10:20:00 9.25
在原始DataFrame中,有三个子组,其中索引之间的间隔保持恒定为2分钟。新的 DataFrame 将只有最后一个索引具有平均值(或任何聚合)值。
过去,我创建了一个单独的列,其中包含日期时间索引之间的时间差,并通过一些不必要的复杂循环,查找大于首选值的时间差,然后汇总之前的测量值并将它们添加到一个单独的列中随着我循环而增长的数据框。我知道这个过程非常低效,所以我一直在寻找一种更快、更优雅的方式。
我们可以将日期时间索引变成一个列,根据那些取last
时间值和mean
列值的值取diff
between rows to find the relative time difference between values. Create a boolean mask where values are gt
the expected time period and groupby agg
。然后恢复索引:
# Make the index a Series which is has more computation options
new_df = df.reset_index()
new_df = (
new_df.groupby(
# Find where index does not follow pattern of 2 minute intervals
new_df['index'].diff().gt(pd.Timedelta(minutes=2)).cumsum()
).agg({
# Get the last index value and the average of the column values
'index': 'last', 'col': 'mean'
}).set_index('index').rename_axis(index=None) # restore index
)
new_df
:
col
2020-06-09 08:50:00 2.50
2020-06-09 09:10:00 12.00
2020-06-09 10:20:00 9.25
设置:
import pandas as pd
df = pd.DataFrame({
'col': [1, 2, 3, 4, 10, 12, 14, 20, 10, 5, 2]
}, index=pd.to_datetime(
['2020-06-09 08:44:00', '2020-06-09 08:46:00',
'2020-06-09 08:48:00', '2020-06-09 08:50:00',
'2020-06-09 09:06:00', '2020-06-09 09:08:00',
'2020-06-09 09:10:00', '2020-06-09 10:14:00',
'2020-06-09 10:16:00', '2020-06-09 10:18:00',
'2020-06-09 10:20:00']
))
df
:
col
2020-06-09 08:44:00 1
2020-06-09 08:46:00 2
2020-06-09 08:48:00 3
2020-06-09 08:50:00 4
2020-06-09 09:06:00 10
2020-06-09 09:08:00 12
2020-06-09 09:10:00 14
2020-06-09 10:14:00 20
2020-06-09 10:16:00 10
2020-06-09 10:18:00 5
2020-06-09 10:20:00 2