基于前一行填充Pandas列(含特殊订单规则)
解决Pandas分组下连续买入订单的序列计数问题
嘿,我来帮你搞定这个Pandas的分组计数需求!咱们先把需求拆解清楚,再一步步写代码实现,避开你之前可能踩过的坑。
核心需求回顾
咱们要实现的是:
- 按
symbol分组处理数据 - 跳过所有
status=EXPIRED的行 - 对连续的BUY订单序列:首笔标记为0,后续每笔递增1
- 遇到SELL订单时,后续的BUY订单开启全新的序列(重新从0开始计数)
- SELL订单的计数可以根据你的需求设为
None/NaN或者其他值(这里默认设为None,你可以按需调整)
步骤1:准备示例数据(方便你测试)
先构造一个和你场景匹配的测试数据集,你可以替换成自己的真实数据:
import pandas as pd # 模拟你的数据集 data = { 'symbol': ['AAPL', 'AAPL', 'AAPL', 'AAPL', 'AAPL', 'MSFT', 'MSFT', 'MSFT'], 'side': ['BUY', 'BUY', 'SELL', 'BUY', 'BUY', 'BUY', 'SELL', 'BUY'], 'status': ['FILLED', 'FILLED', 'FILLED', 'EXPIRED', 'FILLED', 'FILLED', 'FILLED', 'FILLED'] } df = pd.DataFrame(data)
步骤2:先过滤掉无效行
首先要把status=EXPIRED的行直接排除,避免干扰后续计数:
# 过滤过期订单,重置索引避免后续分组出错 df = df[df['status'] != 'EXPIRED'].reset_index(drop=True)
步骤3:标记连续BUY的序列分组
关键一步:我们需要在每个symbol组内,用SELL订单作为分割点,把连续的BUY订单分成不同的序列。这里用cumsum()来实现——每遇到一个SELL,就给序列标记加1,这样后续的BUY就属于新的序列:
# 按symbol分组,生成序列标记:SELL会触发序列切换 df['seq_group'] = df.groupby('symbol')['side'].apply( lambda x: (x == 'SELL').cumsum() )
步骤4:生成BUY序列的递增计数
现在我们可以按symbol + seq_group分组,对每个组内的BUY订单用cumcount()生成从0开始的递增数,非BUY的行(也就是SELL)设为None:
# 生成最终的buy_sequence列 df['buy_sequence'] = df.groupby(['symbol', 'seq_group']).cumcount().where(df['side'] == 'BUY', None)
最终效果展示
运行完上面的代码后,你的数据集会变成这样:
| symbol | side | status | seq_group | buy_sequence |
|---|---|---|---|---|
| AAPL | BUY | FILLED | 0 | 0 |
| AAPL | BUY | FILLED | 0 | 1 |
| AAPL | SELL | FILLED | 1 | None |
| AAPL | BUY | FILLED | 1 | 0 |
| MSFT | BUY | FILLED | 0 | 0 |
| MSFT | SELL | FILLED | 1 | None |
| MSFT | BUY | FILLED | 1 | 0 |
完全符合你的需求:每个连续BUY序列从0开始递增,SELL触发序列重置,过期行被跳过。
可选调整
如果你希望SELL行的buy_sequence显示为0或者其他固定值,只需要修改where的第二个参数即可,比如:
# 把SELL行的buy_sequence设为0 df['buy_sequence'] = df.groupby(['symbol', 'seq_group']).cumcount().where(df['side'] == 'BUY', 0)
内容的提问来源于stack exchange,提问作者nidkil
相关产品推荐
相关产品推荐

