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

pandas/numpy向量化实现查找晚于购买日的最近日期

问题说明

约束:仅可使用pandas、numpy,不可引入其他外部库
现有如下结构的DataFrame:

from datetime import datetime
import pandas as pd

d = pd.DataFrame({
    'purchase_date':[datetime(2022,1,5),datetime(2022,12,10)],
    'shop_visits':[
        [datetime(2021,1,4),datetime(2022,1,6),datetime(2022,1,7)],
        [datetime(2022,5,30),datetime(2022,9,30),datetime(2022,12,10)]
    ]
})

示例数据结构:

purchase_dtshop_visits
2022-01-05[2022-01-04,2022-01-06,2022-01-07]
2022-12-10[2022-05-30,2022-09-30,2022-12-10]

需求:返回每一行shop_visits列表中大于等于对应行purchase_date的最接近日期,上述示例第一行应返回2022-01-06,第二行应返回2022-12-10。

当前基于apply的逐行实现性能较差,需要改用向量化方式实现,现有代码如下:

d.apply(lambda x: min([d for d in x['shop_visits'] if d >= x['purchase_date']],key=lambda d: d-x['purchase_date']),axis=1)
向量化实现方案

可以直接通过numpy广播实现纯向量化计算,完全避免Python层面的逐行循环,性能提升非常明显,代码如下:

import numpy as np

# 将每行的访问日期列表转为二维datetime64数组
visits_array = np.array(d['shop_visits'].tolist(), dtype='datetime64[ns]')
# 将购买日期转为列向量,触发广播逻辑
purchase_array = d['purchase_date'].to_numpy(dtype='datetime64[ns]').reshape(-1, 1)

# 早于购买日期的访问值替换为NaT,每行取最小值即为符合要求的最近日期
result = np.where(visits_array >= purchase_array, visits_array, np.datetime64('NaT')).min(axis=1)
# 结果转为Series赋值回原DataFrame即可
d['nearest_valid_visit'] = pd.Series(result, index=d.index)

运行后得到的结果完全匹配需求:

  • 第一行结果:2022-01-06
  • 第二行结果:2022-12-10

补充说明

  • 该实现对边界场景兼容更好:如果某行shop_visits中不存在大于等于购买日期的记录,会返回NaT,不会像原apply逻辑一样直接抛出ValueError,如果需要保持原逻辑的报错行为,在计算前加一行空值校验即可。
  • 性能表现:数据量越大,该方案对比apply的优势越明显,十万行级数据下性能通常可以提升100倍以上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:18:22