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

为何Pandas中同一.last('7D')过滤对不同Datetime列效果不同?

问题原因分析与解决方案

首先,咱们来拆解为什么两个last('7D')的结果差异这么大:

核心原因:Datetime索引的排序问题

从你提供的act_eng_comp_lw的索引信息可以看到:

DatetimeIndex: 105 entries, 2019-12-26 to 2019-11-27

这个索引是降序排列的(日期从晚到早),而pandas.DataFrame.last()方法的逻辑是:基于索引的时间顺序,选取索引中最后(最末尾)的时间区间。如果索引是降序的,索引末尾的是更早的日期,这时last('7D')会选取从这个最早日期往前推7天的数据,而不是你预期的“最近7天(相对于最新日期)”的数据。

对比第一个正常工作的act_eng_open_lw,它的索引是升序的(2019-12-20到2019-12-26,日期从早到晚),所以last('7D')会正确选取索引末尾的7天(也就是最新的7天)。

另外补充:原始数据中UpdateDTTM存在缺失值(2514 non-null vs 2572总条目),不过这不是本次问题的主因——set_index不会自动丢弃缺失行,但last()会忽略NaT类型的索引值,对你的结果影响有限。

快速修复方案

方案1:设置索引后先排序(推荐)

在调用last()之前,先对索引进行升序排序,确保时间顺序从早到晚:

act_eng_comp_lw = comp_engagements.set_index('UpdateDTTM').sort_index()
act_eng_comp_lw = act_eng_comp_lw.last('7D')

方案2:用布尔索引直接过滤(更直观,不易出错)

如果不想依赖索引排序,直接对UpdateDTTM列进行布尔过滤,明确选取最近7天的数据:

import pandas as pd

# 先找到最新日期
latest_date = comp_engagements['UpdateDTTM'].max()
# 筛选最近7天的记录
act_eng_comp_lw = comp_engagements[comp_engagements['UpdateDTTM'] >= latest_date - pd.Timedelta(days=7)]

这种方式不需要设置索引,逻辑更清晰,也避免了索引排序带来的隐藏问题。

代码重构建议

  1. 封装重复逻辑为函数:你两次处理DataFrame的流程类似,可以把“拆分状态+筛选最近7天”的逻辑封装成函数,减少重复代码:
import pandas as pd

def filter_recent_7_days(df, date_col, status_list):
    # 按状态拆分
    filtered_df = df[df['STATUS'].isin(status_list)]
    # 过滤最近7天(使用布尔索引)
    latest_date = filtered_df[date_col].max()
    return filtered_df[filtered_df[date_col] >= latest_date - pd.Timedelta(days=7)]

# 定义你的状态列表
active_status = [...] # 替换成你的活跃状态值
comp_status = [...] # 替换成你的完成状态值

# 调用函数获取结果
act_eng_open_lw = filter_recent_7_days(engagements, 'OPEN_DATE', active_status)
act_eng_comp_lw = filter_recent_7_days(engagements, 'UpdateDTTM', comp_status)
  1. 提前处理日期列缺失值:原始数据中UpdateDTTM有缺失,建议在拆分前先处理这些缺失值(根据业务逻辑选择丢弃或填充):
# 方式1:丢弃UpdateDTTM缺失的行
engagements_clean = engagements.dropna(subset=['UpdateDTTM'])

# 方式2:用OPEN_DATE填充UpdateDTTM的缺失值(如果业务逻辑允许)
engagements_clean = engagements.copy()
engagements_clean['UpdateDTTM'] = engagements_clean['UpdateDTTM'].fillna(engagements_clean['OPEN_DATE'])
  1. 养成验证索引顺序的习惯:如果一定要用set_index() + last()的方式,每次设置索引后都主动排序,避免因索引顺序导致的意外结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:26