如何用Pandas匹配营业时间DataFrame与含Datetime列的DataFrame
解决Pandas跨DataFrame关联并判断时段的问题
步骤说明与代码实现
先构造示例数据(可替换为你的真实数据):
import pandas as pd import numpy as np # 1. 营业时间表:day_of_week对应0-6(周一到周日,可根据实际调整) hours_df = pd.DataFrame({ 'day_of_week': [0,1,2,3,4,5,6], 'start': ['09:00:00', '09:00:00', '09:00:00', '09:00:00', '09:00:00', '10:00:00', np.nan], 'end': ['18:00:00', '18:00:00', '18:00:00', '18:00:00', '20:00:00', '16:00:00', np.nan] }) # 将start/end转为时间类型(数据已是time类型可跳过) hours_df['start'] = pd.to_datetime(hours_df['start'], format='%H:%M:%S').dt.time hours_df['end'] = pd.to_datetime(hours_df['end'], format='%H:%M:%S').dt.time # 2. 主数据:Datetime索引,包含elec、gas、day_of_week列 dates = pd.date_range('2024-01-01', periods=14, freq='H') main_df = pd.DataFrame({ 'elec': np.random.rand(len(dates)), 'gas': np.random.rand(len(dates)), 'day_of_week': dates.dayofweek }, index=dates)
执行核心操作:
- 按day_of_week关联两个DataFrame
把营业时长信息匹配到主表每一行:
# 先把主表索引转成列,方便合并 merged_df = pd.merge(main_df.reset_index(), hours_df, on='day_of_week', how='left') merged_df.rename(columns={'index': 'ts'}, inplace=True)
- 提取时间并判断是否在营业时段内
从ts中提取时间部分,和对应行的start/end比较:
# 提取ts的时间部分(仅时、分、秒) merged_df['ts_time'] = merged_df['ts'].dt.time # 构造判断条件:start/end非空,且ts_time在两者之间 condition = (merged_df['start'].notna()) & (merged_df['end'].notna()) & (merged_df['ts_time'].between(merged_df['start'], merged_df['end'])) # 新增DuringHours列 merged_df['DuringHours'] = np.where(condition, True, False)
- 整理结果(可选)
把ts放回索引,清理临时列:
merged_df.set_index('ts', inplace=True) merged_df.drop('ts_time', axis=1, inplace=True)
关键说明
between_time无法直接使用的原因:它是针对整个DataFrame的固定时段筛选,而这里每行的营业时段随day_of_week动态变化,必须逐行匹配后判断。- NaN处理:只要
start或end为空,condition就返回False,DuringHours自动设为False,符合需求。 - 时间类型:确保
start/end和ts_time都是datetime.time类型,否则无法正确比较。若数据是字符串格式,需先转换。
内容的提问来源于stack exchange,提问作者Julius
相关产品推荐
相关产品推荐

