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

Python DataFrame:为每个ID匹配最接近HandoverDate的Sent日期

问题描述

现有如下DataFrame:

data = {'SalePrice':[10,10,10,20,20,3,3,1,4,8,8],'HandoverDateA':['2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-04-30','2022-03-30','2022-03-30'],'ID': ['Tom', 'Tom','Tom','Joseph','Joseph','Ben','Ben','Eden','Tim','Adam','Adam'], 'Tranche': ['Red', 'Red', 'Red', 'Red','Red','Blue','Blue','Red','Red','Red','Red'],'Totals':[100,100,100,50,50,90,90,70,60,70,70],'Sent':['2022-01-18','2022-02-19','2022-03-14','2022-03-14','2022-04-22','2022-03-03','2022-02-07','2022-01-04','2022-01-10','2022-01-15','2022-03-12'],'Amount':[20,10,14,34,15,60,25,10,10,40,20],'Opened':['2021-12-29','2021-12-29','2021-12-29','2022-12-29','2022-12-29','2021-12-19','2021-12-19','2021-12-29','2021-12-29','2021-12-29','2021-12-29']}  

需要为每个ID找到不晚于对应HandoverDateA的Sent日期中,与HandoverDateA最接近的日期。尝试过自定义函数和循环分组的方法,但循环速度过慢,需要高效的解决方案。

高效解决方案

步骤1:转换日期列为datetime类型

首先将日期列转为pandas可计算的datetime类型:

import pandas as pd

df = pd.DataFrame(data)
df['HandoverDateA'] = pd.to_datetime(df['HandoverDateA'])
df['Sent'] = pd.to_datetime(df['Sent'])

步骤2:分组获取目标日期

提供两种高效实现方式:

方法一:精准匹配差值逻辑

按ID分组后,筛选符合Sent <= HandoverDateA的记录,计算日期差值绝对值,取差值最小的Sent日期:

def get_nearest_sent(group):
    handover_date = group['HandoverDateA'].iloc[0]
    filtered = group[group['Sent'] <= handover_date]
    if filtered.empty:
        return pd.NaT  # 无符合条件日期时返回空值
    filtered['date_diff'] = abs(filtered['Sent'] - handover_date)
    return filtered.loc[filtered['date_diff'].idxmin(), 'Sent']

result = df.groupby('ID').apply(get_nearest_sent).reset_index(name='NearestSentDate')

方法二:取最大符合条件日期(性能更优)

在Sent <= HandoverDateA的前提下,最大的Sent日期就是最接近HandoverDateA的,直接取最大值即可:

# 先筛选符合条件的行
filtered_df = df[df['Sent'] <= df['HandoverDateA']]
# 分组取最大Sent日期
result = filtered_df.groupby('ID')['Sent'].max().reset_index(name='NearestSentDate')

# 若需保留所有ID(含无符合条件日期的),用merge补全空值
result = df[['ID']].drop_duplicates().merge(result, on='ID', how='left').fillna(pd.NaT)

输出结果示例

最终result的结构如下:

IDNearestSentDate
Adam2022-03-12
Ben2022-03-03
Eden2022-01-04
Joseph2022-04-22
Tim2022-01-10
Tom2022-03-14

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:45:48