如何用Python实现交易数据的反向检索、标记及对应日期提取?
实现指定规则的交易记录标记与日期提取
需求回顾
给定包含trade_name1~20和__date1~20的数据集,需实现以下逻辑:
- 若最后一个非空
trade_name值为PB/MB,且后续所有trade_name列均为空,则标记该记录,并将对应__date值存入新列date - 若最后一个非空
trade_name值为MM/PM/JM,则向前查找最近的PB/MB值,标记记录并将对应__date值存入date - 新增
trade_flag列,符合条件的记录标记为1
解决方案(基于Pandas)
以下是可直接运行的代码,每一步附带注释说明:
import pandas as pd import numpy as np # 1. 读取数据(示例数据模拟,实际替换为你的数据读取方式,如pd.read_csv) data = pd.DataFrame({ 'trade_name1': ['', 'MM', 'PM', 'PM', 'JM', 'MM', 'JM'], '__date1': ['', '1/1/2021', '2/17/2021', '3/3/2021', '3/3/2021', '3/4/2021', '3/4/2021'], 'trade_name2': ['', 'MM', 'PB', 'MB', 'PB', 'MB', 'MB'], '__date2': ['', '9/15/2022', '10/10/2022', '9/13/2022', '3/7/2023', '10/12/2022', '10/21/2022'], 'trade_name3': ['', 'PM', '.', '.', 'PM', '.', '.'], '__date3': ['', '10/10/2022', '.', '.', '4/8/2023', '.', '.'], 'trade_name4': ['', 'PM', '.', '.', '.', '.', '.'], '__date4': ['', '10/29/2022', '.', '.', '.', '.', '.'], # 省略trade_name5~20和__date5~20列,实际数据保留全部列 }) # 2. 预处理:将空字符串和"."替换为NaN,便于空值判断 data = data.replace(['.', ''], np.nan) # 3. 定义单行数据处理函数 def process_row(row): # 提取当前行所有trade_name和对应__date的序列 trade_names = [row[f'trade_name{i}'] for i in range(1, 21)] dates = [row[f'__date{i}'] for i in range(1, 21)] # 筛选出非空的trade_name及其索引 non_empty_trades = [(idx, val) for idx, val in enumerate(trade_names) if pd.notna(val)] if not non_empty_trades: # 无有效交易记录的情况 return (0, np.nan) # 获取最后一个非空交易记录的索引和值 last_idx, last_val = non_empty_trades[-1] # 检查最后一个有效记录后续的所有trade_name是否为空 all_after_empty = all(pd.isna(val) for val in trade_names[last_idx+1:]) # 规则1:最后一个非空值为PB/MB且后续全空 if last_val in ['PB', 'MB'] and all_after_empty: return (1, dates[last_idx]) # 规则2:最后一个非空值为MM/PM/JM,向前查找最近的PB/MB elif last_val in ['MM', 'PM', 'JM']: # 从后往前遍历前面的非空记录,找第一个PB/MB for idx, val in reversed(non_empty_trades[:-1]): if val in ['PB', 'MB']: return (1, dates[idx]) # 若前面无PB/MB,标记为0 return (0, np.nan) else: # 其他情况标记为0 return (0, np.nan) # 4. 将处理函数应用到每一行,生成新列 data[['trade_flag', 'date']] = data.apply(lambda x: pd.Series(process_row(x)), axis=1) # 5. 查看结果(可根据需要调整显示的列) print(data[['trade_name1', '__date1', 'trade_name2', '__date2', 'trade_flag', 'date']])
代码说明
- 数据预处理:统一空值格式,让Pandas能正确识别缺失值,避免判断逻辑出错。
- 单行处理逻辑:
- 先提取每行的交易名称和对应日期序列
- 筛选有效交易记录,确定最后一个有效记录的位置和值
- 按规则判断,返回标记状态和对应日期
- 批量应用:通过
apply函数将处理逻辑批量应用到所有行,高效生成新列。
运行代码后,生成的trade_flag和date列会完全匹配你给出的预期输出。
内容的提问来源于stack exchange,提问作者Sai Paritala
相关产品推荐
相关产品推荐

