首页 > 解决方案 > 如何在 Python 中的 Datetime 索引值之间聚合具有一致 timedelta 的 Pandas DataFrame 行?

问题描述

我有一个 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 将只有最后一个具有平均值(或任何聚合)值的索引。

过去,我创建了一个单独的列,其中包含日期时间索引之间的时间差,并通过一些不必要的复杂循环,查找大于首选值的时间差,并聚合以前的测量值并将它们添加到一个单独的数据帧中,该数据帧随着我的增长而增长环形。我知道这个过程非常低效,所以我一直在寻找一种更快、更优雅的方法。

标签: pythonpandasdataframedatetimegrouping

解决方案


我们可以将日期时间索引变成一列,取diff行之间的值来查找值之间的相对时间差。创建一个布尔掩码,其中值是gt预期的时间段,并groupby agg基于那些采用last时间值和mean列值的值。然后恢复索引:

# 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

推荐阅读