如何为DataFrame添加标记列:判断索引日期是否在多段日期区间内
问题描述
现有两个DataFrame:
df:索引为日期类型,包含ts_code列df_cal:包含多组start_date和end_date字段,每组对应一个日期区间
需求:给df新增一列col,规则为:若df的索引日期落在df_cal的任意一个区间内,col值为1,否则为0。要求禁止使用DataFrame join方法,必须保留df原有索引顺序。此前尝试过单区间处理方案,但无法适配多区间场景。
解决方案
方法一:基于apply的简洁实现(小数据量适用)
先统一日期格式,再通过map遍历每个索引日期,判断是否存在符合条件的区间:
import pandas as pd # 确保df_cal的日期列转为datetime类型 df_cal['start_date'] = pd.to_datetime(df_cal['start_date']) df_cal['end_date'] = pd.to_datetime(df_cal['end_date']) # 定义区间判断逻辑 def check_interval(date): return ((df_cal['start_date'] <= date) & (date <= df_cal['end_date'])).any() # 生成目标列 df['col'] = df.index.map(check_interval).astype(int)
方法二:基于Numpy广播的高性能实现(大数据量优先)
利用Numpy的广播特性,批量完成所有日期的区间判断,性能远高于apply:
import pandas as pd import numpy as np # 统一日期格式 df_cal['start_date'] = pd.to_datetime(df_cal['start_date']) df_cal['end_date'] = pd.to_datetime(df_cal['end_date']) # 转换为Numpy数组,调整维度实现广播 dates = df.index.to_numpy().reshape(-1, 1) start_dates = df_cal['start_date'].to_numpy() end_dates = df_cal['end_date'].to_numpy() # 批量判断每个日期是否在任意区间内 match_mask = ((dates >= start_dates) & (dates <= end_dates)).any(axis=1) df['col'] = match_mask.astype(int)
注意事项
- 必须确保所有涉及的日期字段(df的索引、df_cal的start/end_date)都是
datetime64类型,否则会出现判断错误 - 两种方法均不会修改
df的原有索引顺序,完全符合需求 - 数据量较大时(如百万级行),优先选择方法二,性能提升明显
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

