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

如何用Python获取用户停止日期前的最后交易日期?

解决方法:匹配每个用户停止日期前的最后一笔交易日期

示例数据模拟

先按照示例格式,模拟两个输入DataFrame:

import pandas as pd

# DataFrame1:用户列表及停止日期(含多停止日期的用户)
df1 = pd.DataFrame({
    'user_id': ['A', 'A', 'B', 'C'],
    'stop_date': pd.to_datetime(['2023-01-15', '2023-03-20', '2023-02-10', '2023-04-05'])
})

# DataFrame2:用户交易历史及交易日期
df2 = pd.DataFrame({
    'user_id': ['A', 'A', 'A', 'B', 'B', 'C'],
    'transaction_date': pd.to_datetime(['2023-01-10', '2023-01-20', '2023-03-18', '2023-02-05', '2023-02-12', '2023-04-01']),
    'amount': [100, 200, 150, 50, 75, 300]
})

方案一:用merge_asof高效匹配(推荐)

pd.merge_asof专门用于按时间序列匹配最近的前置/后置记录,适合这类按用户+时间找最近交易的场景:

  1. 先对两个DataFrame按user_id和日期字段排序(merge_asof要求右表必须排序,左表排序可提升匹配效率)
  2. 通过direction='backward'指定匹配小于等于停止日期的最近交易日期
# 排序处理
df1_sorted = df1.sort_values(by=['user_id', 'stop_date'])
df2_sorted = df2.sort_values(by=['user_id', 'transaction_date'])

# 执行匹配
result = pd.merge_asof(
    df1_sorted,
    df2_sorted,
    by='user_id',  # 按用户分组匹配
    left_on='stop_date',
    right_on='transaction_date',
    direction='backward'  # 取stop_date之前的最近交易
)

# 整理输出格式
result = result[['user_id', 'stop_date', 'transaction_date']].rename(
    columns={'transaction_date': 'last_transaction_before_stop'}
)

print(result)

输出结果:

user_id  stop_date last_transaction_before_stop
0       A 2023-01-15                      2023-01-10
1       A 2023-03-20                      2023-03-18
2       B 2023-02-10                      2023-02-05
3       C 2023-04-05                      2023-04-01

方案二:分组筛选法(灵活适配复杂场景)

如果需要保留交易的其他字段,或者有额外筛选逻辑,可采用交叉合并+分组取最大值的方式:

# 交叉合并同一用户的停止日期与交易记录
cross_merge = pd.merge(df1, df2, on='user_id', how='left')

# 筛选交易日期早于等于停止日期的记录
filtered = cross_merge[cross_merge['transaction_date'] <= cross_merge['stop_date']]

# 按用户+停止日期分组,取最晚的交易日期
grouped_result = filtered.groupby(['user_id', 'stop_date'])['transaction_date'].max().reset_index()
grouped_result = grouped_result.rename(columns={'transaction_date': 'last_transaction_before_stop'})

# 补全无前置交易的停止日期记录(对应字段为NaN)
final_result = df1.merge(grouped_result, on=['user_id', 'stop_date'], how='left')

print(final_result)

这个方法的优势是可以灵活扩展,比如同时保留交易金额等字段,只需调整分组时的字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:01:17