如何用Pandas筛选股市多日异动个股的每轮首日数据?
Pandas实现连续异动个股首日筛选
核心需求
按个股分组,仅保留连续异动批次的首日数据:
- 若异动记录之间仅间隔休市日(周末/节假日),视为同一批次,仅留首日
- 若异动记录之间存在非休市的交易日(且无该个股异动记录),则后续异动视为新批次,保留新批次首日
实现步骤
假设已有包含symbol(个股代码)和date(异动日期)的DataFrame,具体操作如下:
1. 预处理:日期格式转换与排序
先确保日期列是datetime类型,并按个股+日期排序,保证数据顺序正确:
import pandas as pd # 示例数据(替换为你的实际数据) data = { 'symbol': ['FOXO', 'FOXO', 'FOXO', 'FOXO', 'FOXO', 'FOXO', 'FOXO', 'FOXO', 'APPL', 'APPL', 'APPL'], 'date': ['2022-12-22', '2022-12-23', '2022-12-27', '2022-12-29', '2022-12-30', '2023-01-03', '2023-01-04', '2023-01-05', '2023-01-03', '2023-01-04', '2023-01-05'] } df = pd.DataFrame(data) # 转换日期格式+排序 df['date'] = pd.to_datetime(df['date']) df = df.sort_values(['symbol', 'date']).reset_index(drop=True)
2. 标记异动批次
按个股分组,计算相邻异动日期之间的非休市交易日数量:
- 若数量>0:说明中间有交易日但无异动,标记为新批次
- 若数量=0:说明仅间隔休市日,属于同一批次
代码实现:
# 生成前一个异动日期 df['prev_date'] = df.groupby('symbol')['date'].shift(1) # 计算两个异动日期之间的非休市交易日数量(不含首尾) def count_business_days_between(row): if pd.isna(row['prev_date']): return 0 # bdate_range生成工作日序列,inclusive='neither'排除首尾 return len(pd.bdate_range(row['prev_date'], row['date'], inclusive='neither')) df['business_days_between'] = df.apply(count_business_days_between, axis=1) # 标记新批次:第一条记录 或 中间有非休市交易日 df['new_batch'] = (df['business_days_between'] > 0) | df['prev_date'].isna() # 按个股累积新批次标记,生成批次ID df['batch_id'] = df.groupby('symbol')['new_batch'].cumsum()
3. 筛选每个批次的首日
按个股+批次ID分组,保留每个组的第一条记录:
# 筛选结果并保留需要的列 result = df.groupby(['symbol', 'batch_id']).head(1)[['symbol', 'date']]
最终结果
运行后得到的result即为符合要求的数据:
| symbol | date |
|---|---|
| APPL | 2023-01-03 |
| FOXO | 2022-12-22 |
| FOXO | 2022-12-29 |
| FOXO | 2023-01-03 |
内容的提问来源于stack exchange,提问作者a7dc
相关产品推荐
相关产品推荐

