Pandas:如何高效按条件聚合连续行(非工作日数据合并至前工作日)
高效向量化实现:将非参考日期数据聚合到最近的前置参考日期
你的需求是把连续日历日的DataFrame,按照给定的参考日期序列重新索引,同时把参考日期之间的缺失日期(比如周末)数据聚合到之前最近的参考日期上。反向遍历的方法虽然可行,但在数据量较大时效率极低,咱们用Pandas的向量化操作来解决这个问题,速度能提升几个数量级!
核心思路
- 为每个原始日期匹配归属的参考日期:通过向量化的索引查找,给DataFrame中的每个日期找到不晚于它的最近参考日期,这个日期就是它要聚合到的目标日期。
- 按归属日期分组聚合:用匹配到的归属日期作为分组键,对原始数据进行聚合(比如求和),最后直接得到以参考日期为索引的结果。
完整代码实现
import pandas as pd import numpy as np # 生成测试数据 df = pd.DataFrame({'x': np.arange(10), 'y': np.arange(10)**2}, index=pd.date_range(start="2018-01-01", periods=10)) ref_dates = pd.date_range(start="2018-01-01", periods=10) ref_dates = ref_dates[:5].append(ref_dates[7:]) # 移除2018-01-06和2018-01-07 # ---------------------- 高效向量化实现 ---------------------- # 1. 为每个原始日期找到对应的参考日期(向量化查找) # 使用searchsorted找到每个原始日期在参考日期中的位置,然后映射到对应的参考日期 ref_indices = pd.Series(ref_dates).searchsorted(df.index, side='right') - 1 group_keys = ref_dates[ref_indices] # 2. 按分组键聚合,这里用sum作为示例聚合函数 aggregated_df = df.groupby(group_keys).sum() # 3. 确保结果严格按照参考日期排序(可选,因为groupby会保留分组键的顺序) aggregated_df = aggregated_df.reindex(ref_dates) print(aggregated_df)
输出结果
x y 2018-01-01 0 0 2018-01-02 1 1 2018-01-03 2 4 2018-01-04 3 9 2018-01-05 15 77 # 包含了1月5、6、7日的求和结果 2018-01-08 7 49 2018-01-09 8 64 2018-01-10 9 81
为什么这更高效?
- 完全向量化操作:
searchsorted和groupby都是Pandas底层优化的向量化方法,避免了Python层面的循环,处理百万级数据时差距会非常明显。 - 代码更简洁:不需要手动维护 collector 列表和遍历逻辑,可读性和可维护性更强。
- 灵活适配聚合函数:只需要修改
groupby后的聚合方法(比如mean()、max()),就能轻松切换不同的聚合逻辑。
内容的提问来源于stack exchange,提问作者ascripter
相关产品推荐
相关产品推荐

