如何高效获取DataFrame中指定人员截至指定时间的最新条目?
高效获取指定人员截至指定时间的最新条目
我有如下DataFrame df:
time person attributes ---------------------------- 1 1 a 2 2 b 3 1 c 4 3 d 5 2 e 6 1 f 7 3 g ... ... ...
需求是编写一个get_latest(request_time, ids)函数,传入指定时间request_time和人员ID列表ids后,返回一个DataFrame,包含每个指定人员截至request_time的最新条目。
比如调用get_latest(request_time = 4.5, ids = [1, 2]),预期返回:
time person attributes ---------------------------- 2 2 b 3 1 c
这是因为人员1和2截至4.5的最新条目分别是time=3和time=2的行。
我原本考虑先截断DataFrame再逐行搜索,效率为O(n),想了解有没有更高效的实现方法或函数。
补充说明:实际场景中time列是Python的datetime类型。
高效实现方案
方法1:分组+索引筛选(通用高效)
适合大部分常规数据量场景,利用Pandas内置的矢量化操作和分组逻辑,底层由C实现,远快于纯Python逐行遍历:
import pandas as pd def get_latest(request_time, ids): # 过滤出目标人员且时间不超过请求时间的行 filtered = df[(df['person'].isin(ids)) & (df['time'] <= request_time)] # 按人员分组,取每组中时间最大的行 latest = filtered.loc[filtered.groupby('person')['time'].idxmax()] return latest.reset_index(drop=True)
方法2:预排序+二分查找(超大数据量最优)
如果数据量极大,预先对数据排序后,用二分查找定位每个人员的最新有效条目,时间复杂度可降至O(m log k)(m为目标人员数,k为单人员平均条目数):
# 预先执行一次排序(只需初始化一次) df_sorted = df.sort_values(by=['person', 'time']).reset_index(drop=True) def get_latest(request_time, ids): result = [] for pid in ids: # 提取当前人员的所有行 pid_rows = df_sorted[df_sorted['person'] == pid] if pid_rows.empty: continue # 二分查找找到最大的<=request_time的位置 idx = pid_rows['time'].searchsorted(request_time, side='right') - 1 if idx >= 0: result.append(pid_rows.iloc[idx]) return pd.DataFrame(result).reset_index(drop=True)
核心优化点
- 避免纯Python循环遍历,优先使用Pandas的内置矢量化操作。
- datetime类型的比较、排序逻辑与数值类型完全兼容,无需额外处理。
内容的提问来源于stack exchange,提问作者Horse
相关产品推荐
相关产品推荐

