You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速DataFrame中匹配每个startdate的最小后续enddate的代码?

加速查找每个startdate对应的最小大于它的enddate

你的问题是在包含startdate和enddate列的DataFrame中,为每个startdate找到大于它的最小enddate,但当前用apply+lambda的逐行遍历方法速度极慢(耗时20秒),且实际数据无法用shift简化。

原方法慢的原因

原代码中apply是逐行循环处理,每次遍历整个enddate列筛选出大于当前startdate的值再取最小值,时间复杂度为O(n²),数据量较大时必然效率低下。

高效优化方案

以下两种方法均基于排序+二分查找,时间复杂度为O(n log n),能大幅提升运行速度:

方法1:利用searchsorted实现二分查找

pandas.Series.searchsorted可以快速找到每个值在排序后的序列中的插入位置,从而直接定位到符合条件的最小enddate。

import pandas as pd
from datetime import datetime

# 构造示例数据
dates = pd.DataFrame({
    'startdate': pd.date_range(start='2000-11-03', end='2021-10-01'),
    'enddate': pd.date_range(start='2000-11-03', end='2021-10-01')
})

# 对enddate排序并去重(去重可避免重复值干扰,可选)
sorted_enddates = dates['enddate'].sort_values().unique()

# 为每个startdate找到在排序后enddate中的插入位置(side='right'确保找大于x的位置)
indices = dates['startdate'].searchsorted(sorted_enddates, side='right')

# 根据索引取值,处理无匹配的边界情况
dates['mindate_after_startdate'] = [
    sorted_enddates[i] if i < len(sorted_enddates) else datetime.today().date()
    for i in indices
]

方法2:使用merge_asof进行近邻匹配

pandas.merge_asof是专门用于按时间/数值进行近邻匹配的工具,适合这种“找最近大于值”的场景,且无需手动处理索引。

import pandas as pd
from datetime import datetime

dates = pd.DataFrame({
    'startdate': pd.date_range(start='2000-11-03', end='2021-10-01'),
    'enddate': pd.date_range(start='2000-11-03', end='2021-10-01')
})

# 准备排序后的enddate数据集(merge_asof要求左右数据集均按匹配键排序)
enddate_df = dates[['enddate']].sort_values('enddate').drop_duplicates().reset_index(drop=True)

# 为了匹配严格大于startdate的值,给startdate加一个极小时间偏移
dates['startdate_shifted'] = dates['startdate'] + pd.Timedelta(1, unit='ns')

# 执行forward方向的近邻匹配:找第一个大于等于startdate_shifted的enddate
result = pd.merge_asof(
    dates.sort_values('startdate_shifted'),
    enddate_df.sort_values('enddate'),
    left_on='startdate_shifted',
    right_on='enddate',
    direction='forward'
)

# 填充无匹配时的默认值,恢复原索引顺序并整理列
result['mindate_after_startdate'] = result['enddate'].fillna(datetime.today().date())
result = result.sort_index().drop(columns=['startdate_shifted', 'enddate'])

效果说明

这两种方法的核心都是通过排序将查找复杂度从O(n)降到O(log n),对于十万级甚至百万级的数据量,运行时间会从几十秒压缩到几百毫秒以内,完全解决原方法的性能问题。

内容的提问来源于stack exchange,提问作者Felton Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 22:55:16