如何创建布尔列标记所有节假日前后各两天?
解决方案:高效生成节假日前后两天标记列
不用循环也能轻松搞定!我们可以利用Pandas的向量化操作来实现这个需求,既简洁又高效,完全避免循环带来的性能问题。
步骤详解
合并所有节假日列
首先我们需要把多个节假日布尔列整合为一个统一的“是否为节假日”标记列,只要任意一个节假日列的值为1,这个合并列就标记为True。生成前后两天的标记
通过shift()函数,我们可以轻松获取“节假日的前两天、前一天、后一天、后两天”对应的日期,然后将这些条件合并,就能得到我们需要的holiday_bookend列。
完整代码实现
import pandas as pd from pandas.tseries.offsets import DateOffset # 生成原始DataFrame date_range = pd.date_range(start = pd.to_datetime("2020-01-10") + DateOffset(days=1), periods = 45, freq = 'D').to_list() peanutbutterday = [0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] jellyday = [0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] crackerday = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0] holiday_dict = {'date':date_range, 'peanutbutterday':peanutbutterday, 'jellyday':jellyday, 'crackerday':crackerday} df = pd.DataFrame.from_dict(holiday_dict) # 1. 合并所有节假日列,得到统一的节假日标记 holiday_cols = ['peanutbutterday', 'jellyday', 'crackerday'] is_holiday = df[holiday_cols].any(axis=1) # 2. 生成四个移位后的条件:节假日的前两天、前一天、后一天、后两天 prev_2_days = is_holiday.shift(-2, fill_value=False) # 当前天是节假日的前两天 prev_1_day = is_holiday.shift(-1, fill_value=False) # 当前天是节假日的前一天 next_1_day = is_holiday.shift(1, fill_value=False) # 当前天是节假日的后一天 next_2_days = is_holiday.shift(2, fill_value=False) # 当前天是节假日的后两天 # 3. 合并所有条件,生成holiday_bookend列 df['holiday_bookend'] = (prev_2_days | prev_1_day | next_1_day | next_2_days).astype(int)
代码说明
any(axis=1):按行检查所有节假日列,只要有一个为1就返回True,实现多列合并。shift()函数:shift(-2):将节假日标记向前移动2行,代表“下下天是节假日,当前天就是前两天”。shift(2):将节假日标记向后移动2行,代表“前两天是节假日,当前天就是后两天”。
- 逻辑或操作
|:将四个条件合并,只要满足其中一个就标记为1,最后用astype(int)把布尔值转为0/1格式。
这种方法完全利用Pandas的向量化运算,比循环快得多,尤其是处理大型数据集时优势明显。
内容的提问来源于stack exchange,提问作者JordanBH
相关产品推荐
相关产品推荐

