给定两个时间戳,如何以“业务分钟数”的形式返回增量

2024-04-27 01:08:52 发布

您现在位置:Python中文网/ 问答频道 /正文

寻找一个干净的功能,最好是在熊猫/Numpy。我目前正在用Pandas的CustomBusinessHour()和TimeDelta()函数构建一些混乱的东西,但我认为一定有更好的方法。如果Pandas有CustomBusinessMinute()功能,这将和len一样简单(pd.U范围(timestamp1,timestamp,freq=CustomBusinessMinute())。你知道吗

我所说的“商务分钟”,是指符合一定标准的一分钟。例如,在我的例子中,这意味着1)不在周末,2)在上午9点到下午5点之间,3)不在联邦假日。你知道吗

谢谢


Tags: 方法函数功能numpypandas标准lentimestamp
2条回答

最后我手工编写了我的假期代码,并基于pd.U范围你知道吗

def isDuringBiz(t):
if (t.hour <= 8 or t.hour >= 17) or t.dayofweek in (5,6) or (t.day == 5 and t.month == 9):
    return False
else:
    return True

def getBizTimedelta(start, end):
bizMinutes = 0
minRange = pd.date_range(start,end,freq='1min')
for min in minRange:
    if isDuringBiz(min):
        bizMinutes += 1
return pd.Timedelta(minutes=bizMinutes)

考虑以下几点:

您只需仔细检查开始和结束日期的各个方面。仔细计算那两天的营业时间。你知道吗

每隔一天,你只需要知道一件事:(1)如果是工作日,如果是:(2)是联邦假日吗

对于日期范围内的每个符合条件的日期,您确切地知道每天有多少“工作分钟”:480分钟。你知道吗

熊猫提供了一种基于美国联邦假日的工作日获取方式。这是最难的部分。其余的应该很容易实现。你知道吗

可能有一种更优雅的方式,但这里有一些东西开始。大多数代码用于处理开始和结束日期。把所有的时间间隔在4行左右。你知道吗

from dateutil.relativedelta import relativedelta
import pandas as pd
from pandas.tseries.offsets import CDay
from pandas.tseries.holiday import USFederalHolidayCalendar

business_day = CDay(calendar=USFederalHolidayCalendar())

def is_weekday(dt):
    return dt.weekday() < 5

def is_holiday(dt):
    return not len(pd.date_range(dt, dt, freq=business_day))

def weekend_or_holiday(dt):
    '''helper function'''
    if not is_weekday(dt):
        return True
    if is_holiday(dt):
        return True
    return False

def start_day_minutes(dt, end_of_day=None):
    '''returns number of business minutes left in the day given a start datetime'''
    if not end_of_day:
        end_of_day = dt.replace(hour=17, minute=0)
    if dt > end_of_day or weekend_or_holiday(dt):
        return 0
    num_of_minutes = (end_of_day - dt).seconds / 60
    return num_of_minutes

def end_day_minutes(dt):
    '''like start_day_minutes, but for the ending day.'''
    start_of_day = dt.replace(hour=9, minute=0)
    if dt < start_of_day or weekend_or_holiday(dt):
        return 0
    num_of_minutes = (dt - start_of_day).seconds / 60
    return num_of_minutes

def business_minutes(t1, t2):
    '''returns num of busniess minutes between t1 and t2'''
    start = t1.replace(hour=0, minute=0) + relativedelta(days=1)
    end = t2.replace(hour=0, minute=0) + relativedelta(days=-1)
    days_between = pd.date_range(start, end, freq=business_day)
    minutes_between = (len(days_between) * 480)
    if (t1.year, t1.day) == (t2.year, t2.day):
        start_end_minutes = start_day_minutes(t1, t2)
    else:
        start_end_minutes = start_day_minutes(t1) + end_day_minutes(t2)

    minutes = minutes_between + start_end_minutes
    return minutes

示例:

start=datetime(2016,1,1)
end=datetime(2017,1,1)
print(business_minutes(start,end))
#120480

相关问题 更多 >