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

Pandas带条件分组cumsum实现自定义信号区间编号问题

Pandas 交易区间分组编号实现方案

你原有代码的问题是将所有R_entry和L_exit都作为分组切割触发点,区间内的R_entry也会导致分组编号递增,不符合忽略区间内重复开仓信号的要求。

实现代码

易读循环版本(适合中小数据量)

import pandas as pd
import numpy as np

# 构造示例DataFrame
df = pd.DataFrame({
    "values":[1,5,7,3,0,9,8,8,7,5,8,1,0,0,0,0,2,5],
    "signal":['L_exit',None,None,'R_entry','R_exit',None,'L_entry','L_exit',None,'R_entry','R_exit','R_entry','R_exit','L_entry','L_exit','L_entry','R_exit',None]
})

in_interval = False
tx_num = 0
tx_col = []

for sig in df['signal']:
    if not in_interval:
        if sig == 'R_entry':
            # 非区间内遇到开仓信号,启动新交易组
            tx_num += 1
            in_interval = True
            tx_col.append(tx_num)
        else:
            tx_col.append(np.nan)
    else:
        tx_col.append(tx_num)
        if sig == 'L_exit':
            # 遇到平仓信号,结束当前区间
            in_interval = False

df['tx'] = tx_col

向量化高性能版本(适合百万级以上大数据量)

# 标记开仓、平仓信号
open_sig = df['signal'].eq('R_entry')
close_sig = df['signal'].eq('L_exit')

# 计算当前是否处于活跃交易区间
in_interval = (open_sig.cumsum() - close_sig.cumsum()).shift(fill_value=0) > 0

# 仅保留非活跃区间的开仓信号作为有效触发点
valid_open = open_sig & ~in_interval

# 生成交易组编号,非区间内赋值为NaN
df['tx'] = valid_open.cumsum().where((in_interval | close_sig) & (valid_open.cumsum() > 0), np.nan)

两种实现输出的tx列和你要求的num列完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:09:03