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

如何在pandas中计算指定日期区间统计值并填充目标列

解决方案

前置准备

首先需要将Date列转换为pandas datetime类型,否则无法进行时间窗口计算:

import pandas as pd
featured_data['Date'] = pd.to_datetime(featured_data['Date'])

核心实现代码

以下代码可以实现按TrainerID分组,统计每行对应日期往前1000天内的胜率,完全匹配你给出的格式要求:

def calc_trainer_win_rate(group):
    # 分组内先按日期升序排序,保证时间顺序正确
    group = group.sort_values('Date').reset_index(drop=True)
    win_rate_list = []
    for _, current_row in group.iterrows():
        current_date = current_row['Date']
        # 筛选1000天内的所有参赛记录(包含当前行)
        time_mask = (current_date - group['Date']).dt.days <= 1000
        period_records = group[time_mask]
        total = len(period_records)
        win_cnt = len(period_records[period_records['Position'] == 1])
        # 格式化输出
        if total == 0:
            rate_str = "0 (0 wins, 0 races)"
        else:
            rate = int(round((win_cnt / total) * 100, 0))
            rate_str = f"{rate} ({win_cnt} wins, {total} race{'s' if total !=1 else ''})"
        win_rate_list.append(rate_str)
    group['Win%'] = win_rate_list
    return group

featured_data = featured_data.groupby('TrainerID', group_keys=False).apply(calc_trainer_win_rate)

原有代码问题说明

你之前的代码存在两个核心错误:

  1. groupby.apply调用时直接计算了整个DataFrame的胜场和累计计数,没有针对每个分组、每行的历史数据做滚动计算,也没有按TrainerID隔离不同训练师的数据。
  2. 完全没有加入时间窗口筛选逻辑,无法限定只统计过去1000天的参赛记录。

大数据量优化方案

如果你的数据量超过10万行,逐行迭代效率较低,可以用pandas时间滚动窗口函数优化:

# 生成胜负标记列
featured_data['is_win'] = (featured_data['Position'] == 1).astype(int)
# 将日期设为索引后按时间排序
featured_data = featured_data.set_index('Date').sort_index()
# 滚动计算1000天内的总参赛数和胜场数
featured_data['total_races'] = featured_data.groupby('TrainerID')['is_win'].rolling('1000D').count().reset_index(drop=True)
featured_data['win_races'] = featured_data.groupby('TrainerID')['is_win'].rolling('1000D').sum().reset_index(drop=True)
# 格式化胜率字符串
featured_data['Win%'] = featured_data.apply(
    lambda x: f"{int(round(x['win_races']/x['total_races']*100,0))} ({int(x['win_races'])} wins, {int(x['total_races'])} race{'s' if x['total_races'] !=1 else ''})" 
    if x['total_races']>0 else "0 (0 wins, 0 races)", 
    axis=1
)
# 清理临时列并恢复普通索引
featured_data = featured_data.drop(columns=['is_win','total_races','win_races']).reset_index()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:24:04