Pandas使用.loc过滤DataFrame后如何追加原表最后一行数据
问题说明
现有用于按时间频率过滤pandas DataFrame的自定义函数如下:
def filter_by_freq(df, frequency): filtered_df = df.copy() if frequency.upper() == 'DAY': pass else: date_obj = filtered_df['Date'].values[0] target_day = pd.to_datetime(date_obj).day target_month = pd.to_datetime(date_obj).month final_date_obj = filtered_df['Date'].values[-1] if frequency.upper() == 'MONTH': filtered_df = filtered_df.loc[filtered_df['Date'].dt.day.eq(target_day)] elif frequency.upper() == 'YEAR': filtered_df = filtered_df.loc[filtered_df['Date'].dt.day.eq(target_day)] filtered_df = filtered_df.loc[filtered_df['Date'].dt.month.eq(target_month)] return filtered_df
需求是在.loc过滤逻辑中额外保留原始DataFrame的最后一行数据。之前尝试按月过滤时编写的filtered_df = filtered_df.loc[(filtered_df['Date'].dt.day.eq(target_day)) | (filtered_df['Date'].dt.date.eq(final_date_obj))]运行后未达到预期效果。
失败原因
之前的代码匹配失败核心是类型不匹配:
filtered_df['Date'].dt.date返回的是Python原生datetime.date类型值- 从
.values属性取到的final_date_obj是numpydatetime64/pandasTimestamp类型,两种类型直接做等值判断会返回False,永远匹配不到目标最后一行。
另外直接比对日期值还容易受Date列的时分秒、时区、重复日期值影响,稳定性差。
修正方案
直接用索引标记最后一行位置,完全绕开日期类型转换的坑,同时兼容月、年两个过滤场景,最后加一步去重避免最后一行本身符合频率规则时出现重复数据:
import pandas as pd def filter_by_freq(df, frequency): filtered_df = df.copy() freq = frequency.upper() # 直接通过索引标记最后一行,不受日期字段类型、值影响 last_row_mask = filtered_df.index == filtered_df.index[-1] if freq == 'DAY': return filtered_df # 从第一行提取基准日、月属性 first_date = pd.to_datetime(filtered_df['Date'].iloc[0]) target_day = first_date.day target_month = first_date.month if freq == 'MONTH': freq_match_mask = filtered_df['Date'].dt.day.eq(target_day) filtered_df = filtered_df.loc[freq_match_mask | last_row_mask] elif freq == 'YEAR': freq_match_mask = (filtered_df['Date'].dt.day.eq(target_day) & filtered_df['Date'].dt.month.eq(target_month)) filtered_df = filtered_df.loc[freq_match_mask | last_row_mask] # 去重,避免最后一行刚好命中频率规则出现重复条目 return filtered_df.drop_duplicates(subset=['Date'])
如果你的DataFrame不是默认连续行索引,把
last_row_mask的定义替换为last_row_mask = filtered_df.reset_index(drop=True).index == len(filtered_df)-1即可正常生效。
内容的提问来源于stack exchange,提问作者Gabriel Tkacz
相关产品推荐
相关产品推荐

