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

Python中按条件查找最大日期值:基金NAV三月收益率计算

解决方案

首先确保日期列是 datetime 类型,这是时间计算的前提:

import pandas as pd
from datetime import timedelta

# 转换date列为datetime格式
df['date'] = pd.to_datetime(df['date'])

方法一:分组逐行处理(适合新手理解,小数据量)

这个逻辑和你Excel的数组公式思路一致,先按基金分组,再为每个日期筛选符合条件的最大历史日期:

# 定义处理单只基金数据的函数
def process_fund(group):
    # 对每个日期,找到该基金下<=当前日期-91天的最大日期
    group['prev_max_date'] = group['date'].apply(
        lambda current_date: group[group['date'] <= current_date - timedelta(days=91)]['date'].max()
    )
    return group

# 按基金分组应用函数
df = df.groupby('fund code').apply(process_fund)

# 关联三个月前的NAV数据
df = df.merge(
    df[['fund code', 'date', 'NAV']].rename(columns={'date': 'prev_max_date', 'NAV': 'prev_NAV'}),
    on=['fund code', 'prev_max_date'],
    how='left'
)

# 计算三月收益率,无匹配数据时显示NaN
df['3_month_return'] = (df['NAV'] / df['prev_NAV']) - 1

方法二:用merge_asof高效匹配(大数据量推荐)

如果数据量较大,逐行apply效率较低,merge_asof是pandas专门用于这类向前匹配最近值的工具,性能更优:

# 按基金代码和日期排序(merge_asof要求输入数据已排序)
df_sorted = df.sort_values(['fund code', 'date'])

# 生成匹配基准:当前日期往前推91天
df_sorted['match_threshold'] = df_sorted['date'] - timedelta(days=91)

# 匹配每个基金下,<=match_threshold的最大日期对应的NAV
df_merged = pd.merge_asof(
    df_sorted,
    df_sorted[['fund code', 'date', 'NAV']].rename(columns={'date': 'prev_date', 'NAV': 'prev_NAV'}),
    left_on='match_threshold',
    right_on='prev_date',
    by='fund code',
    direction='backward'  # 取小于等于阈值的最近日期
)

# 计算收益率
df_merged['3_month_return'] = (df_merged['NAV'] / df_merged['prev_NAV']) - 1

关于你之前代码的问题

你写的 max(filter(lambda x: x<=df['date']-timedelta(days=91))) 存在两个核心问题:

  • df['date'] 是整个列的Series,不是单个日期值,无法直接和单个timedelta做减法后做筛选
  • 没有按基金分组,会把所有基金的日期混在一起计算,逻辑错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:31:32