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

Pandas:为列表元素查找时间序列DataFrame满足条件的首行

问题:在时间序列DataFrame中匹配列表阈值的首个满足条件的行

背景

有一个DataFrame df 和浮点数列表 T,其中df.B是按时间排序的序列:第0个索引对应最新时间戳,最后一个索引对应最旧时间戳。示例如下:

import pandas as pd
df = pd.DataFrame({'A': [1.1, 2.2, 3.3, 4.4], 'B': [5.5, 6.6, 7.7, 8.8]})
T = [t1, t2, ..., tn]  # 浮点数列表

需求

对T中的每个阈值t,在df.B中找到最早满足B >= t的时间点对应的行(即从最旧的时间开始遍历,第一个符合条件的行),返回该行的B值;若没有满足条件的行,返回None。

已尝试的方法及问题

  1. 尝试用apply逐行比较:
df.loc[df.apply(lambda x: x.B >= T, axis=1)]
# 报错:TypeError: unhashable type: 'numpy.ndarray'

错误原因:x.B是单个值,和列表T比较会生成数组,无法作为布尔索引使用。

  1. 尝试用query方法:
df2 = df.query('B >= @T')
# 报错:'Lengths must match to compare'

错误原因:query要求比较的两边长度一致,B是列,T是列表,长度不匹配。

  1. 循环遍历每个t筛选:
[ df[df['B'] >= t] for t in T ]

技术上可行,但后续取首行时会触发警告:pydevd warning: Computing repr of a (list) was slow,因为列表中每个元素是DataFrame对象,生成其字符串表示的开销大,尤其当T规模大时问题更明显。

补充示例

修改df.B后:

T = [3.5, 4.5, 8.0, 8.5, 10.0, 11.0]
df.B = [5.5, 8.8, 6.6, 7.7]

期望输出对应df.B的值为:[7.7, 7.7, 8.8, 8.8, None, None]

高效解决方案

利用numpy的向量操作替代循环,避免性能问题:

import numpy as np

# 将B列反转,按时间从早到晚排列(最旧到最新)
b_reversed = df['B'].values[::-1]
# 对每个t,找到第一个>=t的元素位置(searchsorted默认left模式,找首个大于等于的位置)
indices = np.searchsorted(b_reversed, T, side='left')

# 生成结果:索引在范围内则取对应值,否则返回None
mask = indices < len(b_reversed)
result = np.where(mask, b_reversed[indices], None).tolist()

print(result)
# 输出: [7.7, 7.7, 8.8, 8.8, None, None]

原理说明

  • 反转df.B是为了将时间序列调整为从早到晚的顺序,符合“找最早满足条件的时间点”的遍历逻辑。
  • np.searchsorted是高效的二分查找方法,比逐行遍历快得多,尤其当df和T规模较大时优势明显。
  • 用向量操作替代循环,避免了生成大量DataFrame对象导致的repr警告,同时提升了整体性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:01:02