如何加速pandas中判断美国工作日的Lambda函数运行效率
代码提速方案
你当前代码执行慢的核心原因有两点:
- 把
holidays.US()写在了lambda内部,逐行处理数据时会重复实例化美国假期对象,产生海量无意义的初始化开销 - 用
apply做逐行Python层循环,没有用到pandas/numpy底层的向量化运算能力,性能天然差
以下是按优化效果从高到低排序的可行方案:
方案1:numpy向量化判断(性能最优,通常比原代码快100倍以上)
先确保日期列转为标准datetime类型,再用numpy的原生工作日判断接口做批量计算,全程无Python层循环:import pandas as pd import numpy as np import holidays # 日期列类型转换,为向量化计算做准备 df['date'] = pd.to_datetime(df['date']) # 全局只初始化一次假期对象 us_holidays = holidays.US() # 转换假期为numpy识别的日期格式 holiday_array = np.array(list(us_holidays.keys()), dtype='datetime64[D]') # 批量判断工作日 df['business_day'] = np.is_busday( df['date'].values.astype('datetime64[D]'), holidays=holiday_array )方案2:pandas原生向量化判断(性能和方案1接近,写法更直观)
先筛除周末,再批量判断日期是否落在假期集合内,用短路逻辑减少计算量:df['date'] = pd.to_datetime(df['date']) us_holidays = set(holidays.US().keys()) # 先判断是否为周一到周五,再判断是否不属于节假日 df['business_day'] = (df['date'].dt.weekday < 5) & (~df['date'].isin(us_holidays))方案3:最小改动优化(仅修复冗余初始化问题,性能提升有限)
如果你不想改动原有判断逻辑,至少把假期对象的初始化移到循环外部,避免逐行重复创建实例,这一步就能让原代码速度提升10倍以上,但本质还是逐行循环,性能远不如前两个向量化方案:us_holidays = holidays.US() # 移到lambda外,只初始化一次 df['business_day'] = df['date'].apply(lambda x: isbday(x, holidays=us_holidays))
优化核心原则:所有逐行执行的逻辑里,不要放重复的重量级对象初始化;能走pandas/numpy向量化运算的场景,尽量不要用apply逐行循环。
内容的提问来源于stack exchange,提问作者Tazz
相关产品推荐
相关产品推荐

