如何基于分组与时间范围为DataFrame记录跨日期分配Period
问题:跨日期时间匹配Period字段的实现调整
问题背景
现有两个DataFrame:
period_df:
Group1 Group2 Period Start time End time G1 G2 Period 1 1900-01-01 05:01:00 1900-01-01 06:00:00 G1 G2 Period 2 1900-01-01 06:01:00 1900-01-01 07:00:00 G1 G2 Period 3 1900-01-01 07:01:00 1900-01-01 08:00:00 G1 G2 Period 4 1900-01-01 08:01:00 1900-01-01 09:00:00 G1 G2 Period 5 1900-01-01 09:01:00 1900-01-01 10:00:00
records_df:
Group1 Group2 Original time G1 G2 1900-01-01 05:05:00 G1 G2 1900-01-01 07:23:00 G1 G2 1900-01-00 07:45:00 G1 G2 1900-01-02 09:57:00 G1 G2 1900-01-02 08:23:00
需求说明
基于Group1、Group2分组,将records_df每条记录的Original time与period_df中对应分组的Start time、End time的时间部分匹配,为每条记录分配对应的Period字段。
当前实现与问题
原有实现函数如下:
def assign_period(record): for _, period in period_df.iterrows(): if record['Group1'] == period['Group1'] and \ record['Group2'] == period['Group2'] and \ period['Start time'] <= record['Original time'] <= period['End time']: return period['Period'] return None
调用后结果:
records_df['Period'] = records_df.apply(assign_period, axis=1) Group1 Group2 Original time Period G1 G2 1900-01-01 05:05:00 Period 1 G1 G2 1900-01-01 07:23:00 Period 3 G1 G2 1900-01-00 07:45:00 None G1 G2 1900-01-02 09:57:00 None G1 G2 1900-01-02 08:23:00 None
问题在于:原有逻辑比较完整的日期时间,导致跨日期的记录无法匹配,而需求是忽略日期,仅按时间部分匹配。预期输出应为:
Group1 Group2 Original time Period G1 G2 1900-01-01 05:05:00 Period 1 G1 G2 1900-01-01 07:23:00 Period 3 G1 G2 1900-01-00 07:45:00 Period 3 G1 G2 1900-01-02 09:57:00 Period 5 G1 G2 1900-01-02 08:23:00 Period 4
解决方案
步骤1:转换日期时间列类型
首先将所有日期时间字符串转换为datetime类型,方便提取时间部分:
# 转换period_df的时间列 period_df['Start time'] = pd.to_datetime(period_df['Start time']) period_df['End time'] = pd.to_datetime(period_df['End time']) # 转换records_df的时间列 records_df['Original time'] = pd.to_datetime(records_df['Original time'])
步骤2:修改匹配函数
调整函数逻辑,仅比较日期时间的时间部分(时分秒):
def assign_period(record): # 提取当前记录的时间部分 record_time = record['Original time'].time() # 筛选同分组的周期规则 same_group_periods = period_df[(period_df['Group1'] == record['Group1']) & (period_df['Group2'] == record['Group2'])] for _, period in same_group_periods.iterrows(): # 提取周期的起止时间部分 start_time = period['Start time'].time() end_time = period['End time'].time() if start_time <= record_time <= end_time: return period['Period'] return None
步骤3:调用函数并验证
records_df['Period'] = records_df.apply(assign_period, axis=1) print(records_df)
执行后即可得到预期的匹配结果。
优化说明
- 先筛选同分组的周期规则,避免遍历所有周期,提升效率
- 明确提取时间部分进行比较,完全忽略日期差异,符合需求
内容的提问来源于stack exchange,提问作者z star
相关产品推荐
相关产品推荐

