在Pandas 0.18中实现日期分桶与日期区间归属判断
高效解决Pandas 0.18中的日期分桶匹配问题
嘿,我明白你的痛点——Pandas 0.18确实没有merge_asof这种方便的工具,但咱们完全可以用numpy.searchsorted来实现高效的日期分桶匹配,这个方法靠二分查找,处理几百行数据毫无压力,甚至规模再大些也能hold住。
具体步骤来啦:
1. 先把分桶数据理清楚
首先得把你的分桶日期转成datetime类型,还要按时间排序,这样才能建立正确的区间逻辑:
import pandas as pd import numpy as np # 你的原始分桶数据 d = {'buckets': ['1D', '1W', '1M'], 'dates': ['03-05-2018', '10-05-2018', '03-06-2018']} date_buckets = pd.DataFrame(data=d) # 转换日期格式(这里是MM-DD-YYYY,所以用'%m-%d-%Y') date_buckets['dates'] = pd.to_datetime(date_buckets['dates'], format='%m-%d-%Y') # 按日期排序,保证分桶的时间顺序正确 date_buckets_sorted = date_buckets.sort_values('dates').reset_index(drop=True)
2. 实现分桶匹配逻辑
咱们用searchsorted来定位每个目标日期对应的分桶。这里的逻辑是:每个分桶对应一个截止日期,比如1D覆盖到2018-03-05,1W覆盖到2018-05-10,1M覆盖到2018-06-03。目标日期落在哪个截止日期之前,就属于对应的分桶:
# 提取排序后的日期数组和分桶标签 bucket_dates = date_buckets_sorted['dates'].values bucket_labels = date_buckets_sorted['buckets'].values # 批量处理的向量化方法(比apply快很多) def assign_buckets(target_dates): # 先把目标日期转成datetime target_dates = pd.to_datetime(target_dates, format='%m-%d-%Y') # 用searchsorted找到每个日期对应的位置,side='right'找第一个大于目标日期的截止点 indices = np.searchsorted(bucket_dates, target_dates.values, side='right') - 1 # 处理边界情况:如果日期早于所有分桶的起始截止点,归到第一个分桶 indices[indices < 0] = 0 # 映射到对应的分桶标签 return bucket_labels[indices]
3. 测试和批量应用
先测试你的示例日期:
# 测试单个日期 print(assign_buckets(['07-05-2018'])) # 输出 ['1W'],完美符合预期
如果有几百行数据要处理,直接传给函数就行:
# 示例待处理数据集 df = pd.DataFrame({ 'target_dates': [ '01-05-2018', '07-05-2018', '15-05-2018', '01-06-2018', '05-06-2018' ] }) # 给数据集添加分桶列 df['bucket'] = assign_buckets(df['target_dates'])
处理后的结果会是这样:
| target_dates | bucket |
|---|---|
| 01-05-2018 | 1D |
| 07-05-2018 | 1W |
| 15-05-2018 | 1M |
| 01-06-2018 | 1M |
| 05-06-2018 | 1M |
为什么这个方法高效?
numpy.searchsorted是基于二分查找实现的,每一个日期的查找时间复杂度是O(log n),几百行数据处理起来几乎是瞬间完成的,比循环遍历或者低效的merge方式快得多,完全满足你的需求。
另外要注意:确保日期格式的format参数和你的实际数据匹配,要是你的日期是DD-MM-YYYY格式,记得把%m-%d-%Y改成%d-%m-%Y,避免解析错误哦。
内容的提问来源于stack exchange,提问作者N Evans
相关产品推荐
相关产品推荐

