如何用Pandas合并时间间隔小于1分钟的行并汇总数据?
合并时间间隔小于1分钟的连续行(Pandas实现)
需求说明
我有一个包含时间戳的表格,需要合并行之间时间间隔小于1分钟的连续行,具体规则:
- 当
time_break小于60时,将当前行的time_delta与上一行的time_delta求和 - 用前一行的
ts_start更新当前行的ts_start - 保留分组起始行的
time_break值
输入数据
import pandas as pd df = pd.DataFrame({'ts_start': [1647854644, 1647855323, 1647855454, 1647855521, 1647858807, 1647858858, 1647858970], 'ts_end': [1647854699, 1647855421, 1647855521, 1647856205, 1647858810, 1647858958, 1647859020], 'time_break': [105.0, 624.0, 33.0, 0.0, 2602.0, 48.0, 12.0], 'time_delta': [55, 98, 67, 625, 3, 100, 50]})
期望输出
df_out = pd.DataFrame({'ts_start': [1647854644, 1647855323, 1647858807], 'ts_end': [1647854699, 1647856205, 1647859020], 'time_break': [105.0, 624.0, 2602.0], 'time_delta': [55, 790, 153]})
尝试的代码(存在问题)
我试过循环方法,但运行缓慢且无法正确处理连续多行行的合并:
for i in range(1, len(df)): try: if 0 <= df.iloc[i, df.columns.get_loc('time_break')] <= 60: df.iloc[i, df.columns.get_loc('time_delta')] += df.iloc[i-1, df.columns.get_loc('time_delta')] df.iloc[i, df.columns.get_loc('ts_start')] = df.iloc[i-1, df.columns.get_loc('ts_start')] df.iloc[i, df.columns.get_loc('time_break')] = df.iloc[i, df.columns.get_loc('ts_start')] - df.iloc[i-2, df.columns.get_loc('ts_end')] df.drop(index=i-1, inplace=True) df = df.reset_index(drop=True) except IndexError: break;
解决方案:分组聚合(groupby)实现
核心思路是先构建分组标识,把需要合并的连续行归为同一组,再对每组执行聚合计算,避免循环的低效问题。
步骤1:生成分组ID
通过time_break >= 60标记新分组的起始点,再用cumsum()生成连续的分组ID,确保所有需要合并的行属于同一组:
# 标记分组起始:time_break >=60 的行是新分组的开始 df['group_id'] = (df['time_break'] >= 60).cumsum() # 修正第一行的分组ID(默认归为第一个分组) if len(df) > 0: df.loc[0, 'group_id'] = 1
步骤2:分组聚合
对每个分组执行以下操作:
ts_start:取分组内最小值(保留最靠前的起始时间)ts_end:取分组内最大值(保留最靠后的结束时间)time_break:取分组内第一行的值(保留原分组起始行的间隔)time_delta:对分组内所有值求和
代码实现:
df_out = df.groupby('group_id').agg( ts_start=('ts_start', 'min'), ts_end=('ts_end', 'max'), time_break=('time_break', 'first'), time_delta=('time_delta', 'sum') ).reset_index(drop=True)
完整代码
import pandas as pd # 输入数据 df = pd.DataFrame({'ts_start': [1647854644, 1647855323, 1647855454, 1647855521, 1647858807, 1647858858, 1647858970], 'ts_end': [1647854699, 1647855421, 1647855521, 1647856205, 1647858810, 1647858958, 1647859020], 'time_break': [105.0, 624.0, 33.0, 0.0, 2602.0, 48.0, 12.0], 'time_delta': [55, 98, 67, 625, 3, 100, 50]}) # 生成分组ID df['group_id'] = (df['time_break'] >= 60).cumsum() if len(df) > 0: df.loc[0, 'group_id'] = 1 # 分组聚合得到结果 df_out = df.groupby('group_id').agg( ts_start=('ts_start', 'min'), ts_end=('ts_end', 'max'), time_break=('time_break', 'first'), time_delta=('time_delta', 'sum') ).reset_index(drop=True) print(df_out)
输出结果
ts_start ts_end time_break time_delta 0 1647854644 1647854699 105.0 55 1 1647855323 1647856205 624.0 790 2 1647858807 1647859020 2602.0 153
内容的提问来源于stack exchange,提问作者vasssabi96
相关产品推荐
相关产品推荐

