如何将Pandas代码中的日历分钟差替换为业务分钟差并适配fillna?
替换日历分钟差为业务分钟差并适配原分组填充逻辑
原代码逻辑回顾
原代码通过按ID分组,用diff(-1)计算当前行与下一行set时间的倒序差(取正值),最后用每组最后一行的closed与set的日历分钟差填充缺失值,得到newtime列。现在需要将所有时间差替换为俄罗斯地区的业务分钟差(工作日10:00-21:00,排除法定节假日)。
解决方案
核心是用business_duration替换原生的日历时间差计算,同时适配原分组逻辑中"每组最后一行用closed与set的差填充"的规则。具体步骤如下:
- 预处理时间列:将字符串格式的时间转换为
datetime类型 - 定义业务时间计算函数:封装
businessDuration的调用逻辑,统一计算两个时间点的业务分钟数 - 分组处理时间差:按
ID分组后,分别计算非最后一行的组内时间差、最后一行的set与closed时间差
完整代码
import pandas as pd import holidays as pyholidays from datetime import time, datetime from business_duration import businessDuration # 初始化数据集 df = pd.DataFrame({ 'ID': ['aaa', 'aaa', 'aaa', 'bbb', 'ccc', 'ccc'], 'closed': ['2023-03-28 22:00', '2023-03-28 22:00', '2023-03-28 22:00', '2023-03-29 23:00', '2023-03-27 22:00', '2023-03-27 22:00'], 'set': ['2023-03-27 19:00', '2023-03-28 19:30', '2023-03-28 20:00', '2023-03-27 22:00', '2023-03-25 19:00', '2023-03-26 19:30'], 'message_time': ['19:05', '19:40', '21:00', '22:10', '19:05', '19:40'] }) # 转换时间列为datetime类型 df['closed'] = pd.to_datetime(df['closed']) df['set'] = pd.to_datetime(df['set']) # 定义业务分钟差计算函数 def calc_bus_minutes(start_dt, end_dt): holidaylist_RU = pyholidays.Russia(years=[start_dt.year, end_dt.year]) start_hour = time(10, 0, 0) end_hour = time(21, 0, 0) return businessDuration( startdate=start_dt, enddate=end_dt, starttime=start_hour, endtime=end_hour, holidaylist=holidaylist_RU, unit='min' ) # 按ID分组处理时间差 def process_group(group): group['next_set'] = group['set'].shift(-1) group['newtime'] = group.apply( lambda row: calc_bus_minutes(row['set'], row['next_set']) if pd.notna(row['next_set']) else calc_bus_minutes(row['set'], row['closed']), axis=1 ) group.drop('next_set', axis=1, inplace=True) return group # 应用分组逻辑并输出结果 df = df.groupby('ID', group_keys=False).apply(process_group) print(df[['ID', 'set', 'closed', 'newtime']])
关键逻辑说明
- 替代原
diff(-1).mul(-1):用shift(-1)获取下一行的set时间,通过自定义函数计算业务分钟差,替换原生日历时间差 - 适配原
fillna(c-s):通过pd.notna(row['next_set'])判断是否为组内最后一行,若是则计算set与closed的业务分钟差,完全匹配原填充逻辑 - 动态适配节假日:函数自动根据起止时间的年份加载对应节假日,避免硬编码年份
内容的提问来源于stack exchange,提问作者luibrain
相关产品推荐
相关产品推荐

