pandas DataFrame交替买卖交易行如何无需循环向量化合并为单条记录
Pandas交替买卖交易行合并的向量化实现方法
有两种简洁的向量化实现方案,均不需要逐行循环,性能远优于手动遍历:
方案1:分组聚合实现(推荐)
利用索引构造交易分组ID,直接通过分组聚合一次性提取对应字段:
import pandas as pd # 原始数据 values = pd.DataFrame({ 'Date': ['2010-01-03', '2011-02-06', '2012-03-06', '2012-05-15', '2013-04-12', '2014-03-18'], 'Signal': [1, -1, 1, -1, 1, -1], 'Close': [100, 103, 106, 108, 111, 114] }) # 构造交易分组ID,每两行对应一个完整交易 values['trade_id'] = values.index // 2 + 1 # 命名聚合直接生成目标结构 new_data = values.groupby('trade_id').agg( Begin_Date = ('Date', 'first'), End_Date = ('Date', 'last'), Trade_Open = ('Close', 'first'), Trade_Close = ('Close', 'last') ).reset_index(names='Trade') # 调整列名匹配要求 new_data = new_data.rename(columns={ 'Begin_Date': 'Begin Date', 'End_Date': 'End Date', 'Trade_Open': 'Trade Open', 'Trade_Close': 'Trade Close' })
方案2:拆分合并实现
按奇偶索引拆分买入、卖出行后直接拼接:
# 提取所有买入行(索引为偶数)、卖出行(索引为奇数) buy = values.iloc[::2].reset_index(drop=True) sell = values.iloc[1::2].reset_index(drop=True) # 拼接生成目标表 new_data = pd.DataFrame({ 'Trade': range(1, len(buy)+1), 'Begin Date': buy['Date'], 'End Date': sell['Date'], 'Trade Open': buy['Close'], 'Trade Close': sell['Close'] })
注意事项
以上两种方案默认原始数据严格遵循「买入-卖出」交替的顺序,且不存在缺失配对。如果实际数据可能存在配对异常,可先通过分组校验Signal字段的合法性:
# 校验每个交易组的信号是否符合 买入(1)+卖出(-1) 的规则 valid_check = values.groupby('trade_id')['Signal'].agg(lambda x: (x.iloc[0]==1) and (x.iloc[1]==-1)).all() if not valid_check: print("存在异常配对的交易数据,请先清洗后再合并")
内容的提问来源于stack exchange,提问作者Jonathan Bechtel
相关产品推荐
相关产品推荐

