You need to enable JavaScript to run this app. pandas按日期保留列内最后一次值为1的信号,其余同天置0
优惠活动
大模型
产品
解决方案
定价
更多

pandas按日期保留列内最后一次值为1的信号,其余同天置0

按自然日保留当日最后一次1值止损信号的实现方案

你的需求本质是按自然日把长时序数据拆成单天片段,仅保留每个片段里时间最晚的一次信号为1的位置,同天其他所有信号值全部置0,最终保证任意自然日最多只出现一次值为1的信号行。

之前尝试drop_duplicates、普通groupby没得到预期结果的原因很简单:

  • drop_duplicates是基于列值做全局去重,只会机械地删除重复的1值,根本不会考虑时间顺序,更没法精准定位到当天最后一个1的位置
  • 常规groupby取聚合值的写法,会把同一个分组下所有行的信号值统一成聚合结果,比如取max就会把同天所有行都变成1,根本做不到只留单个1、其余置0的效果

新手友好的直观循环实现

这种写法逻辑和手动处理的思路完全一致,逐行调试时很容易定位问题,没有晦涩的API:

import pandas as pd

# 先备份原始信号值,避免后续赋值操作覆盖原始数据
original_signal = df['Long Stop Loss Signal'].copy()
# 初始化目标列,全量填充0
df['Long Stop Loss Signal'] = 0

# 基于datetime类型的索引提取自然日维度,逐天拆分分组
for trade_date, group in df.groupby(df.index.date):
    # 定位当前自然日内所有原始信号为1的行
    daily_1_rows = group[original_signal.loc[group.index] == 1]
    # 若当天存在1值信号,取时间最晚的那个1的位置赋值为1
    if not daily_1_rows.empty:
        last_one_position = daily_1_rows.index[-1]
        df.loc[last_one_position, 'Long Stop Loss Signal'] = 1

适配长周期数据的高性能向量化实现

当数据覆盖多年时长、总行数达到几十万甚至百万规模时,循环的运行效率会偏低,可直接用pandas原生向量化运算实现,运行速度会提升几个量级,最终输出结果和循环写法完全一致:

# 备份原始信号值
original_signal = df['Long Stop Loss Signal'].copy()

# 生成布尔标记:每个自然日内,仅最后一个1值的位置标记为True
last_one_mask = original_signal.groupby(df.index.date).transform(
    lambda daily_series: (
        daily_series.index == daily_series[daily_series == 1].index[-1]
        if (daily_series == 1).any()
        else False
    )
)
# 把布尔标记转为0/1值,替换原有信号列
df['Long Stop Loss Signal'] = last_one_mask.astype(int)

以上两种实现的输出完全匹配你给出的目标格式:

  • 2008-01-01当天原始信号的最后一个1出现在03:30,转换后仅该位置为1,其余位置(包括之前09:56、03:29出现的1)全部置0
  • 2008-01-02当天连续的1信号最后停在03:28,转换后仅该位置为1,其余全天的连续1全部置0
  • 若某自然日全程没有出现值为1的信号,当天所有行的信号值自动保持为0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 07:06:05