为何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)]
这种方式不需要设置索引,逻辑更清晰,也避免了索引排序带来的隐藏问题。
代码重构建议
- 封装重复逻辑为函数:你两次处理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)
- 提前处理日期列缺失值:原始数据中
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'])
- 养成验证索引顺序的习惯:如果一定要用
set_index()+last()的方式,每次设置索引后都主动排序,避免因索引顺序导致的意外结果。
内容的提问来源于stack exchange,提问作者pmichaud
相关产品推荐
相关产品推荐

