获取两个Pandas Series间对象计数字典的最快方法
高效实现区间元素计数方案
针对你处理20万级datetime数据时的性能瓶颈,推荐用numpy二分查找的向量化实现——底层基于C语言编写,性能比Python循环或pandas apply高几个数量级,完全适配你的场景。
核心思路
利用numpy.searchsorted对排序后的目标值数组做二分查找,快速定位每个区间[ss[i], ee[i]]的左右边界,边界索引的差值就是该区间内的元素数量。时间复杂度为O(n log n + m log n)(n为vals长度,m为区间数量),远超你之前的O(m+n)循环方案。
示例代码(基础数值场景)
import numpy as np # 输入数据 ss = [0, 10, 20, 30] ee = [3, 15, 23, 40] vals = [0, 1, 2, 5, 7, 10, 11, 16, 21, 22, 23, 29, 31, 35, 45] # 1. 将vals转为排序后的numpy数组(若原始数据未排序必须执行此步) vals_sorted = np.sort(vals) # 2. 二分查找每个区间的左右边界索引 left_indices = np.searchsorted(vals_sorted, ss, side="left") # 第一个>=ss[i]的位置 right_indices = np.searchsorted(vals_sorted, ee, side="right") # 第一个>ee[i]的位置 # 3. 计算每个区间的元素数量并转为字典 counts = right_indices - left_indices result = dict(zip(ss, counts)) print(result) # 输出: {0: 3, 10: 2, 20: 3, 30: 2}
适配datetime类型的Pandas场景
如果你的vals是带datetime索引的Pandas Series,只需将datetime索引转为numpy的datetime64数组即可直接复用上述逻辑:
import numpy as np import pandas as pd # 模拟带datetime索引的Series dates = pd.date_range(start="2023-01-01", periods=200000, freq="H") vals = pd.Series(range(200000), index=dates) # 定义datetime区间(示例) ss = pd.to_datetime(["2023-01-01", "2023-01-10", "2023-01-20"]) ee = pd.to_datetime(["2023-01-03", "2023-01-15", "2023-01-25"]) # 1. 提取并排序datetime索引 dt_vals_sorted = np.sort(vals.index.to_numpy()) # 2. 二分查找边界 left_indices = np.searchsorted(dt_vals_sorted, ss.to_numpy(), side="left") right_indices = np.searchsorted(dt_vals_sorted, ee.to_numpy(), side="right") # 3. 生成结果字典 counts = right_indices - left_indices result = dict(zip(ss, counts))
方案优势
numpy.searchsorted是向量化的二分查找实现,避免了Python循环的性能开销- 排序仅需一次
O(n log n)操作,后续每个区间的查找都是O(log n),处理20万级数据毫无压力 - 原生兼容
datetime64类型,无需额外的类型转换成本
内容的提问来源于stack exchange,提问作者pseudoabdul
相关产品推荐
相关产品推荐

