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

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是numpy datetime64/pandas Timestamp类型,两种类型直接做等值判断会返回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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:27:20