Pandas:无需遍历生日列表,匹配日期区间内的生日
问题:无需遍历生日列表实现日期区间匹配?
我在Pandas DataFrame中存储了一组日期区间(例如每月的起始和结束日期),同时有一个生日列表。希望为DataFrame新增一列,存储落在对应StartDate和EndDate区间内的生日日期(可存为列表)。
示例代码:
import pandas as pd import datetime as dt end = [x for x in pd.date_range(dt.date(2022,1,1),periods=12, freq=pd.offsets.MonthEnd(1)).values] start = [x for x in pd.date_range(dt.date(2022,1,1),periods=12, freq=pd.offsets.MonthBegin(1)).values] dates = [(x, y) for x, y in zip(start, end)] df = pd.DataFrame(dates, columns = ['StartDate', 'EndDate']) birthdays = [dt.date(2022, 6, 17), dt.date(2022, 10, 7),dt.date(2022, 10, 12), dt.date(2022, 11 ,15)]
期望的DataFrame结果:
from numpy import nan solution = [nan, nan, nan, nan, nan, [dt.date(2022, 6, 17)], nan, nan, nan, [dt.date(2022, 10, 7),dt.date(2022, 10, 12)], [dt.date(2022, 11 ,15)], nan] df['Solution'] = solution
请问是否可以不遍历生日列表,实现这种匹配查找?
解决方案
可以通过Pandas向量化操作实现,无需显式遍历生日列表,核心思路是利用广播机制生成匹配矩阵,再聚合结果:
- 先将生日列表转为Pandas的日期Series,统一日期格式:
birthdays_series = pd.Series(pd.to_datetime(birthdays))
- 生成广播式的布尔匹配矩阵:
通过将DataFrame的日期列转为二维数组([:, None]),与生日Series进行广播比较,得到每行区间对应的生日匹配结果:
# 生成每行区间与所有生日的匹配条件矩阵 match_matrix = (birthdays_series >= df['StartDate'].values[:, None]) & (birthdays_series <= df['EndDate'].values[:, None])
- 基于匹配矩阵聚合生成结果列:
遍历匹配矩阵的每一行,筛选出符合条件的生日并转为日期列表,无匹配则填充空值:
df['Solution'] = [ birthdays_series[mask].dt.date.tolist() if mask.any() else pd.NA for mask in match_matrix ]
执行后就能得到符合预期的结果,整个过程没有显式遍历生日列表,而是利用Pandas的向量化运算提升效率。
内容的提问来源于stack exchange,提问作者keynesiancross
相关产品推荐
相关产品推荐

