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

单调时序DataFrame偏移匹配优化:提速及最近邻匹配需求

问题描述

现有一个含单调时序ts的DataFrame,结构如下:

ts   |   value1  |   value2
11          9            x
19         10            x
26          x            x 
29          x            x
32          x            x

需求为:对每个value1,找到x秒前刚好超过计算时间点(ts-x)的value2。示例:当x=10时,32-10=22,刚好超过22的ts为26,取该点的value2;29-10=19,对应ts=19,取该点的value2。

本人编写了如下O(n)复杂度的循环代码,但运行速度极慢:

x = 10
i1 = 0
row_num = df.shape[0]

for i in range(row_num):
    cur_row = df.iloc[i]
    cur_t = cur_row.ts
    cur_v = cur_row.value1

    delay_t = cur_t - x
    while i1 < row_num and df.iloc[i1].ts < delay_t:
        i1 += 1
    delay_v = df.iloc[i1].value2
    df.iloc[i,3] = cur_v - delay_v

现咨询两个问题:

  1. 该代码运行缓慢的原因是什么?如何优化?优先采用向量化实现。
  2. 若能解决第一个问题,能否进一步优化为找到最接近ts-x的value2?例如32-10=22,比较19和26与22的距离,取ts=19对应的value2。

问题解答

1. 代码慢的原因与向量化优化

慢的核心原因

算法本身是O(n)复杂度,但循环中反复调用df.iloc[i]属于逐行操作,Pandas的行级读取会频繁触发数据定位和对象创建,带来大量额外开销;同时直接在循环中修改df.iloc[i,3],也不符合DataFrame的批量优化设计,导致实际运行效率极低。

向量化优化方案

利用Pandas内置的searchsorted方法,它针对有序序列做二分查找(单查询O(logn),整体O(nlogn)),全程向量化操作,速度远快于循环:

import pandas as pd

x = 10
# 计算每个时间点对应的延迟目标时间
df['delay_t'] = df['ts'] - x

# 找到每个delay_t对应的第一个>=它的ts的索引
target_indices = df['ts'].searchsorted(df['delay_t'], side='left')

# 提取对应value2并计算结果
df['delay_v'] = df['value2'].iloc[target_indices].values
df['result'] = df['value1'] - df['delay_v']

如果ts是严格单调递增的,该方案完全匹配需求,且性能比原始循环提升几个数量级。

2. 查找最接近ts-x的value2

通过searchsorted分别获取延迟时间的左、右插入点,再比较两个相邻点与目标时间的距离,选择更近的那个:

x = 10
df['delay_t'] = df['ts'] - x

# 获取左(第一个>=delay_t)、右(第一个>delay_t)插入点
left_indices = df['ts'].searchsorted(df['delay_t'], side='left')
right_indices = df['ts'].searchsorted(df['delay_t'], side='right')

# 遍历处理边界与距离比较
final_indices = []
for idx, dt in enumerate(df['delay_t']):
    left = left_indices[idx]
    right = right_indices[idx]
    
    if left == 0:
        final_indices.append(0)
    elif right == len(df):
        final_indices.append(len(df)-1)
    else:
        dist_left = dt - df['ts'].iloc[left-1]
        dist_right = df['ts'].iloc[right] - dt
        final_indices.append(left-1 if dist_left <= dist_right else right)

# 提取对应value2并计算结果
df['closest_v'] = df['value2'].iloc[final_indices].values
df['closest_result'] = df['value1'] - df['closest_v']

该方案仅在最后一步做少量循环处理边界,核心查找逻辑仍用向量化的searchsorted,整体效率依然远高于原始循环。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:33:25