You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:29:56