如何无循环高效计算df2的total列?基于df时间区间匹配
高效统计时间区间覆盖次数的Pandas实现
问题描述
现有两个Pandas DataFrame:
df(时间区间数据)
| start | end |
|---|---|
| 6:15:00 | 6:15:06 |
| 6:15:00 | 6:15:00 |
| 6:15:00 | 6:15:01 |
| 6:15:01 | 6:15:06 |
| 6:15:01 | 6:15:15 |
| 6:15:01 | 6:15:09 |
| 6:15:01 | 6:15:09 |
| 6:15:02 | 6:15:06 |
| 6:15:02 | 6:15:08 |
| 6:15:02 | 6:15:09 |
df2(待统计时间点)
| periods (1 sec timedelta) | total |
|---|---|
| 6:15:00 | 2 |
| 6:15:01 | 5 |
| 6:15:02 | 8 |
需求:为df2中的每个period,统计df中满足start <= period且end >= period的行数,作为df2的total值。循环处理每行效率极低,求无需循环的高效实现方式。
高效实现方案
核心思路是利用Pandas的向量化运算替代循环,充分发挥numpy广播机制的性能优势,避免逐行处理的冗余计算。
完整代码
import pandas as pd from datetime import datetime, timedelta # 初始化时间区间DataFrame df = pd.DataFrame({ 'start': ['6:15:00', '6:15:00', '6:15:00', '6:15:01', '6:15:01', '6:15:01', '6:15:01', '6:15:02', '6:15:02', '6:15:02'], 'end': ['6:15:06', '6:15:00', '6:15:01', '6:15:06', '6:15:15', '6:15:09', '6:15:09', '6:15:06', '6:15:08', '6:15:09'] }) # 将时间字符串转换为带基准日期的datetime类型(避免单独time类型的运算限制) base_date = datetime(2023, 10, 6) df['start'] = pd.to_datetime(base_date.strftime('%Y-%m-%d ') + df['start']) df['end'] = pd.to_datetime(base_date.strftime('%Y-%m-%d ') + df['end']) # 初始化待统计时间点DataFrame start_period = datetime(2023, 10, 6, 6, 15, 0) end_period = datetime(2023, 10, 6, 6, 15, 2) df2 = pd.DataFrame({ "periods (1 sec timedelta)": pd.date_range(start=start_period, end=end_period, freq='1S'), "total": None }) # 向量化匹配:通过广播生成布尔矩阵,判断每个period是否被df的区间覆盖 mask = (df['start'].values <= df2['periods (1 sec timedelta)'].values[:, None]) & \ (df['end'].values >= df2['periods (1 sec timedelta)'].values[:, None]) # 对每行求和,得到每个period对应的覆盖次数 df2['total'] = mask.sum(axis=1) print(df2)
关键细节说明
- 时间类型转换:将单独的时间字符串转为带基准日期的
datetime,避免time类型在向量化运算中的兼容性问题 - 广播机制:利用numpy广播特性,将df2的一维时间数组与df的一维区间数组进行批量比较,生成
(len(df2), len(df))的布尔矩阵,每个元素对应一组period与区间的匹配结果 - 高效统计:对布尔矩阵的每行直接求和,一次性得到所有period的覆盖次数,全程无循环,性能比逐行处理提升数倍
输出结果
periods (1 sec timedelta) total 0 2023-10-06 06:15:00 2 1 2023-10-06 06:15:01 5 2 2023-10-06 06:15:02 8
内容的提问来源于stack exchange,提问作者unstoppable
相关产品推荐
相关产品推荐

