Pandas无需apply按指定时间区间计算Timedelta索引数据集均值
无apply的矢量化实现方案
以下两种方案均和你原有计算逻辑(区间左闭右开[Start, Stop))完全对齐,底层为C实现,数据量大时性能比逐行apply高数十到上百倍:
方案1:IntervalIndex + 分组聚合(最简洁通用)
# 构造左闭右开的区间索引,匹配原有逻辑 intervals = pd.IntervalIndex.from_arrays(ranges["Start"], ranges["Stop"], closed="left") # 为my_data每一行匹配所属的区间下标,不属于任何区间的返回-1 my_data["group_id"] = intervals.get_indexer(my_data.index) # 过滤无效行后分组求均值,再对齐ranges的行顺序 result = my_data[my_data["group_id"] != -1].groupby("group_id")["data"].mean().reindex(range(len(ranges)))
输出结果:
0 7.5 1 60.0 2 122.5 Name: data, dtype: float64
方案2:merge_asof实现(适合区间无重叠的场景)
# 给每个区间加唯一id ranges = ranges.reset_index(names="range_id") # 按时间维度排序(乱序数据必须先执行这一步) my_data_sorted = my_data.sort_index() ranges_sorted = ranges.sort_values("Start") # 匹配每个数据行所属的区间 merged = pd.merge_asof(my_data_sorted, ranges_sorted, left_index=True, right_on="Start") # 过滤超出区间右边界的行,分组求均值后对齐原ranges顺序 result = merged[merged.index < merged["Stop"]].groupby("range_id")["data"].mean().reindex(range(len(ranges)))
注意事项
如果后续需要调整区间开闭规则,只需修改IntervalIndex的closed参数即可:
closed="left":左闭右开[a,b),匹配你原有逻辑closed="right":左开右闭(a,b]closed="both":闭区间[a,b]closed="neither":开区间(a,b)
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

