如何使用Python Pandas实现满足条件后填充后续行值为0直到当月末
Pandas 按条件填充当月后续行数据实现方案
实现逻辑
- 按年月对DataFrame进行分组,天然匹配“截止到当月月末”的范围要求
- 对每个月的分组数据,找到第一个满足
Returns < m的触发位置 - 将触发位置之后到当月月末的所有Returns值统一填充为0
完整实现代码
基于你提供的示例代码,新增实现逻辑如下:
import pandas as pd import numpy as np from datetime import datetime, timedelta # 你提供的原始生成数据代码 date_today = datetime.now() days = pd.date_range(date_today, date_today + timedelta(365), freq='D') np.random.seed(seed=1111) data = np.random.randint(1, high=100, size=len(days)) df = pd.DataFrame({'test': days, 'Price': data}) df = df.set_index('test') df['Returns']=df['Price'].pct_change() # ---------------------- 新增需求实现代码 ---------------------- m = -0.5 # 自定义阈值 # 增加年月辅助列用于分组 df['year_month'] = df.index.to_period('M') def process_month_group(group): # 找到当前月第一个满足Returns小于m的触发日期 # 新增notna判断避免NaN值参与条件计算,不需要可以删掉该判断 trigger_date = group[group['Returns'].notna() & (group['Returns'] < m)].index.min() if pd.notna(trigger_date): # 触发日期之后的所有行Returns填充为0 # 如果需要把触发日期本身也填充为0,把 > 改为 >= 即可 group.loc[group.index > trigger_date, 'Returns'] = 0 return group # 按年月分组应用处理逻辑 df = df.groupby('year_month', group_keys=False).apply(process_month_group) # 删除辅助列 df = df.drop(columns=['year_month']) # ---------------------- 结果验证代码 ---------------------- # 打印所有触发点所在月份的数据,确认填充逻辑正确 trigger_dates = df[df['Returns'] < m].index for d in trigger_dates: print(f"触发日期:{d.strftime('%Y-%m-%d')}") print("当月数据如下:") print(df[df.index.to_period('M') == d.to_period('M')][['Price', 'Returns']]) print("-"*50)
注意事项
- 该实现默认取每个月最早的触发点,同月份后续的触发点会被之前的填充逻辑覆盖,符合常规业务场景
- 日频年数据处理效率高,无冗余循环,时间复杂度为O(n)
- 可根据实际需求调整是否将触发位置本身也填充为0,调整代码中判断符号即可
内容的提问来源于stack exchange,提问作者Macro Panda
相关产品推荐
相关产品推荐

