Pandas按时间间隔与区间重叠规则合并DataFrame行的实现问题
Pandas区间合并需求实现代码
首先修正原问题中df1的构造代码(原代码缺少data外层列表,无法正常运行):
import pandas as pd df1 = pd.DataFrame(data=[["shoe", 4, 6, 0.110, 10], ["bracelet", 22, 25, 0.115, 40], ["belt", 2, 5, 0.120, 12], ["socks", 1, 3, 0.422, 8], ["scarf", 10, 12, 0.630, 6], ["skirt", 4, 6, 0.9, 5], ["bag", 9, 13, 1.131, 4], ["watch", 1, 4, 1.8, 5], ["sweater", 4, 5, 5.5, 14], ["jeans", 1, 6, 5.6, 14]], columns=['item','low','high','time', 'price'])
步骤1:划分时间候选组
按照规则,连续行时间差小于1秒归为同一候选组:
# 相邻行时间差≥1秒时开启新的候选组 df1['time_group'] = (df1['time'].diff() >= 1).cumsum()
步骤2:候选组内合并重叠区间
对每个时间候选组内的[low, high]区间做重叠合并:
def merge_overlap_interval(group): # 按区间左端点low排序,方便合并判断 group = group.sort_values('low', ignore_index=True) group['merge_id'] = 0 current_max_high = group.loc[0, 'high'] current_merge_id = 0 for idx in range(1, len(group)): if group.loc[idx, 'low'] <= current_max_high: # 区间重叠,归入当前合并组 group.loc[idx, 'merge_id'] = current_merge_id # 更新合并组的最大右端点 current_max_high = max(current_max_high, group.loc[idx, 'high']) else: # 区间不重叠,开启新合并组 current_merge_id += 1 group.loc[idx, 'merge_id'] = current_merge_id current_max_high = group.loc[idx, 'high'] return group # 按时间候选组分组应用区间合并逻辑 df1 = df1.groupby('time_group', group_keys=False).apply(merge_overlap_interval) # 生成全局唯一合并组标识 df1['final_group'] = df1['time_group'].astype(str) + '_' + df1['merge_id'].astype(str)
步骤3:按规则聚合合并组
def group_agg_rule(group): # 取组内price最高、price相同时time最小的行 priority_row = group.sort_values(['price', 'time'], ascending=[False, True]).iloc[0] return pd.Series({ 'item': priority_row['item'], 'low': group['low'].min(), 'high': group['high'].max(), 'time': priority_row['time'], 'price': priority_row['price'], 'time_min': group['time'].min(), 'time_max': group['time'].max() }) df2 = df1.groupby('final_group', group_keys=False).apply(group_agg_rule).reset_index(drop=True)
注:原问题给出的预期输出中bracelet的price写为10属于笔误,实际按规则应取该行price=40,代码运行结果会修正该错误。
内容的提问来源于stack exchange,提问作者scientist
相关产品推荐
相关产品推荐

